This conversation actually prompted me to take another look, and I just implemented a fix on 3.1 and 3.2 (trunk) branches. Cross context events are now posted in threads separate from commit threads, so this deadlock should be gone.
In theory the fix can be applied to 3.0.x too… Andrus On Sep 6, 2012, at 1:53 PM, Andrus Adamchik <[email protected]> wrote: > Yeah, unfortunately this is a known problem that we need to solve: > > https://issues.apache.org/jira/browse/CAY-957 > > It was partially fixed in Cayenne 3.1: > > https://issues.apache.org/jira/browse/CAY-1653 > > But there's still a condition when that can happen. As a workaround you can > create nested contexts that are subclasses of DataContext, overriding > 'setChannel' (3.0.x) or 'attachToChannel' (3.1.x) to suppress this line: > > EventUtil.listenForChannelEvents(channel, mergeHandler); > > This way peer nested context events won't get propagated, and the deadlock > should not occur. > > Andrus > > > On Sep 6, 2012, at 7:16 PM, Ramiro Aparicio wrote: >> Hi, >> >> I have been debugging some strange errors in our web app that seems to be >> related to context and threads, let me explain, we are using Cayenne 3.0.1 >> using WebApplicationContextFilter to bind the context to threads, in some >> parts of the application is not so difficult to be processing several AJAX >> request from the same user, and they go to different threads but using the >> same context (because of the context per session setup) and this causes race >> condition errors from time to time. >> To avoid that I have switched to use nested context per request, this allows >> us to use the filter as ever but avoid messing contexts in different threads >> at the same time, but this only works with single requests, when I get 5 o 6 >> threads working at the same time they just reach to a deadlock state every >> time I try. >> >> Every thread stops at: >> >> Daemon Thread [http-8443-2] (Suspended) >> DispatchQueue.dispatchEvent(EventManager$Dispatch) line: 53 >> EventManager.dispatchEvent(EventManager$Dispatch) line: 359 >> EventManager.postEvent(EventObject, EventSubject) line: 330 >> DataContext(BaseContext).fireDataChannelChanged(Object, GraphDiff) line: >> 349 >> DataContext.fireDataChannelChanged(Object, GraphDiff) line: 1591 >> DataContext.onContextFlush(ObjectContext, GraphDiff, boolean) line: 1060 >> DataContext(BaseContext).onSync(ObjectContext, GraphDiff, int) line: 300 >> DataContext.flushToParent(boolean) line: 1106 >> DataContext.commitChanges() line: 1045 >> >> Except one that stops at: >> >> Daemon Thread [http-8443-3] (Suspended) >> DataContextMergeHandler.graphChanged(GraphEvent) line: 103 >> GeneratedMethodAccessor88.invoke(Object, Object[]) line: not available >> DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: 25 >> Method.invoke(Object, Object...) line: 597 >> Invocation.fire(Object[]) line: 202 >> EventManager$Dispatch.fire(Invocation) line: 420 >> DispatchQueue.dispatchEvent(Collection<Invocation>, Dispatch) line: 156 >> DispatchQueue.dispatchEvent(EventManager$Dispatch) line: 57 >> EventManager.dispatchEvent(EventManager$Dispatch) line: 359 >> EventManager.postEvent(EventObject, EventSubject) line: 330 >> DataContext(BaseContext).fireDataChannelChanged(Object, GraphDiff) line: >> 349 >> DataContext.fireDataChannelChanged(Object, GraphDiff) line: 1591 >> DataContext.onContextFlush(ObjectContext, GraphDiff, boolean) line: 1060 >> DataContext(BaseContext).onSync(ObjectContext, GraphDiff, int) line: 300 >> DataContext.flushToParent(boolean) line: 1106 >> DataContext.commitChanges() line: 1045 >> >> Maybe someone can help me with this deadlock or at least point me to a >> different setup to bypass the thread safety errors I am having from time to >> time. >> >> Thanks in advance. >> Ramiro Aparicio >> > >
