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
> 

Reply via email to