We are having issues with conversations being timed out in 1.0.1GA.  This may 
be fixed in the CVS version.

We have set the org.jboss.seam.core.Manager.conversationTimeout to 15 seconds 
through use of a components.xml.  

After pausing on a conversational page for 30 seconds, we attempt to see if the 
conversation did timeout.  When we click the "Save" link on our page, it allows 
the request to go through without redirecting to the "No Conversation" page.  

In order to debug the issue, we set some breakpoints in 
Manager.setLongRunningConversation, Manager.storeConversation, and 
Manager.conversationTimeout to
see how things are playing out.

When we click the Save link, the first thing that happens is the conversation 
is restored.

At this point, the longRunningConversation is set to "true".
Stack trace

  | Thread [http-0.0.0.0-8080-2] (Suspended (entry into method 
setLongRunningConversation in Manager))
  |     Manager.setLongRunningConversation(boolean) line: 294
  |     Manager.restoreConversation(String) line: 587
  |     Manager.restoreConversation(Map) line: 521
  |     AbstractSeamPhaseListener.restoreAnyConversationContext(FacesContext) 
line: 41
  |     SeamPhaseListener.afterPhase(PhaseEvent) line: 63
  |     PhaseListenerManager.informPhaseListenersAfter(PhaseId) line: 89
  |     LifecycleImpl.restoreView(FacesContext, PhaseListenerManager) line: 181
  |     LifecycleImpl.execute(FacesContext) line: 66
  |     FacesServlet.service(ServletRequest, ServletResponse) line: 137
  |     ApplicationFilterChain.internalDoFilter(ServletRequest, 
ServletResponse) line: 252
  |     ApplicationFilterChain.doFilter(ServletRequest, ServletResponse) line: 
173
  |     ExtensionsFilter.doFilter(ServletRequest, ServletResponse, FilterChain) 
line: 144
  |     ApplicationFilterChain.internalDoFilter(ServletRequest, 
ServletResponse) line: 202
  |     ApplicationFilterChain.doFilter(ServletRequest, ServletResponse) line: 
173
  |     SeamRedirectFilter.doFilter(ServletRequest, ServletResponse, 
FilterChain) line: 30
  |     ApplicationFilterChain.internalDoFilter(ServletRequest, 
ServletResponse) line: 202
  |     ApplicationFilterChain.doFilter(ServletRequest, ServletResponse) line: 
173
  |     ReplyHeaderFilter.doFilter(ServletRequest, ServletResponse, 
FilterChain) line: 96
  |     ApplicationFilterChain.internalDoFilter(ServletRequest, 
ServletResponse) line: 202
  |     ApplicationFilterChain.doFilter(ServletRequest, ServletResponse) line: 
173
  |     StandardWrapperValve.invoke(Request, Response) line: 213
  |     StandardContextValve.invoke(Request, Response) line: 178
  |     SecurityAssociationValve.invoke(Request, Response) line: 175
  |     BasicAuthenticator(AuthenticatorBase).invoke(Request, Response) line: 
524
  |     JaccContextValve.invoke(Request, Response) line: 74
  |     StandardHostValve.invoke(Request, Response) line: 126
  |     ErrorReportValve.invoke(Request, Response) line: 105
  |     StandardEngineValve.invoke(Request, Response) line: 107
  |     CoyoteAdapter.service(Request, Response) line: 148
  |     Http11Processor.process(InputStream, OutputStream) line: 869
  |     
Http11Protocol$JmxHttp11ConnectionHandler(Http11BaseProtocol$Http11ConnectionHandler).processConnection(TcpConnection,
 Object[]) line: 664
  |     PoolTcpEndpoint.processSocket(Socket, TcpConnection, Object[]) line: 527
  |     MasterSlaveWorkerThread.run() line: 112
  |     ThreadWithAttributes(Thread).run() line: 595
  | 

Because the longRunningConversation is "true", the conversation is touched.  
When the conversation is touched, the ConversationEntry.lastRequestTime is 
updated to the current time.  


  |    public void storeConversation(ContextAdaptor session, Object response)
  |    ....
  |     if ( isLongRunningConversation() )
  |       {
  |          touchConversationStack();
  |          if ( !Seam.isSessionInvalid() ) 
  |          {
  |             forceMutableComponentReplication();
  |             storeLongRunningConversation(response);
  |          }
  |       }
  |       else
  |       {
  |          discardTemporaryConversation(session, response);
  |       }
  |       
  | 
Stack trace

  | Thread [http-0.0.0.0-8080-1] (Suspended (entry into method 
touchConversationStack in Manager))
  |     Manager.touchConversationStack() line: 164
  |     Manager.storeConversation(ContextAdaptor, Object) line: 368
  |     AbstractSeamPhaseListener.storeAnyConversationContext(FacesContext) 
line: 69
  |     SeamStateManager.saveSerializedView(FacesContext) line: 45
  |     FaceletViewHandler.renderView(FacesContext, UIViewRoot) line: 578
  |     LifecycleImpl.render(FacesContext) line: 384
  |     FacesServlet.service(ServletRequest, ServletResponse) line: 138
  |     ApplicationFilterChain.internalDoFilter(ServletRequest, 
ServletResponse) line: 252
  |     ApplicationFilterChain.doFilter(ServletRequest, ServletResponse) line: 
173
  |     ExtensionsFilter.doFilter(ServletRequest, ServletResponse, FilterChain) 
line: 144
  |     ApplicationFilterChain.internalDoFilter(ServletRequest, 
ServletResponse) line: 202
  |     ApplicationFilterChain.doFilter(ServletRequest, ServletResponse) line: 
173
  |     SeamRedirectFilter.doFilter(ServletRequest, ServletResponse, 
FilterChain) line: 30
  |     ApplicationFilterChain.internalDoFilter(ServletRequest, 
ServletResponse) line: 202
  |     ApplicationFilterChain.doFilter(ServletRequest, ServletResponse) line: 
173
  |     ReplyHeaderFilter.doFilter(ServletRequest, ServletResponse, 
FilterChain) line: 96
  |     ApplicationFilterChain.internalDoFilter(ServletRequest, 
ServletResponse) line: 202
  |     ApplicationFilterChain.doFilter(ServletRequest, ServletResponse) line: 
173
  |     StandardWrapperValve.invoke(Request, Response) line: 213
  |     StandardContextValve.invoke(Request, Response) line: 178
  |     SecurityAssociationValve.invoke(Request, Response) line: 175
  |     BasicAuthenticator(AuthenticatorBase).invoke(Request, Response) line: 
524
  |     JaccContextValve.invoke(Request, Response) line: 74
  |     StandardHostValve.invoke(Request, Response) line: 126
  |     ErrorReportValve.invoke(Request, Response) line: 105
  |     StandardEngineValve.invoke(Request, Response) line: 107
  |     CoyoteAdapter.service(Request, Response) line: 148
  |     Http11Processor.process(InputStream, OutputStream) line: 869
  |     
Http11Protocol$JmxHttp11ConnectionHandler(Http11BaseProtocol$Http11ConnectionHandler).processConnection(TcpConnection,
 Object[]) line: 664
  |     PoolTcpEndpoint.processSocket(Socket, TcpConnection, Object[]) line: 527
  |     MasterSlaveWorkerThread.run() line: 112
  |     ThreadWithAttributes(Thread).run() line: 595
  | 

Finally, the conversation timeout check occurs.  Because the 
ConversationEntry.lastRequestTime was updated a few milliseconds ago, the delta 
is never going to be bigger than the conversationEntry.getTimeout().  Note that 
at this point conversationEntry.getTimeout() is correctly returning "15000".


  | /**
  |     * Clean up timed-out conversations
  |     */
  |    public void conversationTimeout(ExternalContext externalContext)
  |    {
  |       long currentTime = System.currentTimeMillis();
  |       Iterator<Map.Entry<String, ConversationEntry>> entries = 
getConversationIdEntryMap().entrySet().iterator();
  |       while ( entries.hasNext() )
  |       {
  |          Map.Entry<String, ConversationEntry> entry = entries.next();
  |          ConversationEntry conversationEntry = entry.getValue();
  |          long delta = currentTime - conversationEntry.getLastRequestTime();
  |          if ( delta > conversationEntry.getTimeout() )
  |          {
  |             String conversationId = entry.getKey();
  |             log.debug("conversation timeout for conversation: " + 
conversationId);
  |             ContextAdaptor session = 
ContextAdaptor.getSession(externalContext, true);
  |             destroyConversation(conversationId, session, entries);
  |          }
  |       }
  |    }
  | 

Stack trace

  | Thread [http-0.0.0.0-8080-1] (Suspended (entry into method 
conversationTimeout in Manager))
  |     Manager.conversationTimeout(ExternalContext) line: 316
  |     SeamPhaseListener.afterPhase(PhaseEvent) line: 93
  |     PhaseListenerManager.informPhaseListenersAfter(PhaseId) line: 89
  |     LifecycleImpl.render(FacesContext) line: 391
  |     FacesServlet.service(ServletRequest, ServletResponse) line: 138
  |     ApplicationFilterChain.internalDoFilter(ServletRequest, 
ServletResponse) line: 252
  |     ApplicationFilterChain.doFilter(ServletRequest, ServletResponse) line: 
173
  |     ExtensionsFilter.doFilter(ServletRequest, ServletResponse, FilterChain) 
line: 144
  |     ApplicationFilterChain.internalDoFilter(ServletRequest, 
ServletResponse) line: 202
  |     ApplicationFilterChain.doFilter(ServletRequest, ServletResponse) line: 
173
  |     SeamRedirectFilter.doFilter(ServletRequest, ServletResponse, 
FilterChain) line: 30
  |     ApplicationFilterChain.internalDoFilter(ServletRequest, 
ServletResponse) line: 202
  |     ApplicationFilterChain.doFilter(ServletRequest, ServletResponse) line: 
173
  |     ReplyHeaderFilter.doFilter(ServletRequest, ServletResponse, 
FilterChain) line: 96
  |     ApplicationFilterChain.internalDoFilter(ServletRequest, 
ServletResponse) line: 202
  |     ApplicationFilterChain.doFilter(ServletRequest, ServletResponse) line: 
173
  |     StandardWrapperValve.invoke(Request, Response) line: 213
  |     StandardContextValve.invoke(Request, Response) line: 178
  |     SecurityAssociationValve.invoke(Request, Response) line: 175
  |     BasicAuthenticator(AuthenticatorBase).invoke(Request, Response) line: 
524
  |     JaccContextValve.invoke(Request, Response) line: 74
  |     StandardHostValve.invoke(Request, Response) line: 126
  |     ErrorReportValve.invoke(Request, Response) line: 105
  |     StandardEngineValve.invoke(Request, Response) line: 107
  |     CoyoteAdapter.service(Request, Response) line: 148
  |     Http11Processor.process(InputStream, OutputStream) line: 869
  |     
Http11Protocol$JmxHttp11ConnectionHandler(Http11BaseProtocol$Http11ConnectionHandler).processConnection(TcpConnection,
 Object[]) line: 664
  |     PoolTcpEndpoint.processSocket(Socket, TcpConnection, Object[]) line: 527
  |     MasterSlaveWorkerThread.run() line: 112
  |     ThreadWithAttributes(Thread).run() line: 595
  | 

If you artificially put a 20 second sleep in the Manager.conversationTimeout 
function, it will correctly detect that the conversation did indeed timeout.  
It will then call destroyConversation.  However, it fails to redirect to the 
outcome we specified in our @Conversational annotation.  Instead, it
allows our "Save" request to continue as normal and renders the "Saved" page.  

Finally, if we click a link on this "Saved" page, it detects that the 
conversation did indeed timeout, and thus redirects
to the @Conversational Annotations's ifNotBegunOutcome.

So there are multiple issues:

1. The long running conversation will never timeout since the lastRequestTime 
is always updated before the conversationTimeout check occurs.
2. Even if the conversation timeout check picks up the conversation was 
timedout, it still allows the method to continue.  Note that fixing Issue 1, may
prevent Issue 2 from ever occurring.




View the original post : 
http://www.jboss.com/index.html?module=bb&op=viewtopic&p=3970380#3970380

Reply to the post : 
http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&p=3970380
_______________________________________________
jboss-user mailing list
[email protected]
https://lists.jboss.org/mailman/listinfo/jboss-user

Reply via email to