Session Replication Valve Cross Context Dispatching

2005-06-23 Thread Eric Dalquist
I have been working on getting session replication working for a set of 
web applications that use cross context dispatching.


I ran into a problem where the session for the context the request is 
being made to is being replicated correctly but the session for the 
context(s) being dispatched to are not being replicated at all.


The contextA servlet handling the request modifies its session then does 
a cross context dispatch to another servlet in contextB which also 
modifies its session. In this case two different sessions (one for 
contextA and another for contextB) have been modified. After the request 
is complete only the contextA session is replicated.


After a fair amount of digging into the tomcat code I think I have an 
understanding of how session replication works and what is going on in 
this case.


The following stack trace was captured just before the servlet in 
contextB is called. The stack items above and below the lines is tomcat 
code.


From what I've been able to figure out configuring Clustering in tomcat 
adds the ReplicationValve to the chain of valves the request goes 
through before getting to the servlet. After the servlet is called this 
valve calls the Manager for this context to inform it the request is 
complete and that replication should be done. The ReplicationValve is in 
the bottom 1/3 of the stack.


In the top 1/3 of the stack is the tomcat code to execute a cross 
context dispatch. There is no ReplicationValve or other filter in this 
stack so after the dispatch is complete there is no code called to 
inform the manager of the other context that the request is complete and 
replication should be performed.


Is there any way to get tomcat to replicate the session for contexts 
that are accessed via cross context dispatches during a request?


Thank you
   -Eric Dalquist

Thread [TSP-Processor3] (Suspended)
  ApplicationFilterChain.internalDoFilter(ServletRequest, 
ServletResponse) line: 234
  ApplicationFilterChain.doFilter(ServletRequest, ServletResponse) 
line: 173

  ApplicationDispatcher.invoke(ServletRequest, ServletResponse) line: 672
  ApplicationDispatcher.doInclude(ServletRequest, ServletResponse) 
line: 574

  ApplicationDispatcher.include(ServletRequest, ServletResponse) line: 499
--
  PortletInvokerImpl.invoke(PortletRequest, PortletResponse, Integer) 
line: 120

  PortletInvokerImpl.action(ActionRequest, ActionResponse) line: 68
  PortletContainerImpl.processPortletAction(PortletWindow, 
HttpServletRequest, HttpServletResponse) line: 150

  CPortletAdapter.setRuntimeData(ChannelRuntimeData, String) line: 578
  
MultithreadedPrivilegedCacheableDirectResponseCharacterChannelAdapter(MultithreadedCharacterChannelAdapter).setRuntimeData(ChannelRuntimeData) 
line: 29
  ChannelManager.feedRuntimeDataToChannel(IChannel, HttpServletRequest) 
line: 896
  ChannelManager.processRequestChannelParameters(HttpServletRequest) 
line: 841
  ChannelManager.startRenderingCycle(HttpServletRequest, 
HttpServletResponse, UPFileSpec) line: 981
  UserInstance.processPortletActionIfNecessary(HttpServletRequest, 
HttpServletResponse) line: 203
  UserInstance.writeContent(HttpServletRequest, HttpServletResponse) 
line: 177
  PortalSessionManager.doGet(HttpServletRequest, HttpServletResponse) 
line: 253
  PortalSessionManager(HttpServlet).service(HttpServletRequest, 
HttpServletResponse) line: 689
  PortalSessionManager(HttpServlet).service(ServletRequest, 
ServletResponse) line: 802

--
  ApplicationFilterChain.internalDoFilter(ServletRequest, 
ServletResponse) line: 252
  ApplicationFilterChain.doFilter(ServletRequest, ServletResponse) 
line: 173

  StandardWrapperValve.invoke(Request, Response) line: 213
  StandardContextValve.invoke(Request, Response) line: 178
  StandardHostValve.invoke(Request, Response) line: 126
  ReplicationValve.invoke(Request, Response) line: 145
  ErrorReportValve.invoke(Request, Response) line: 105
  StandardEngineValve.invoke(Request, Response) line: 107
  CoyoteAdapter.service(Request, Response) line: 148
  JkCoyoteHandler.invoke(Msg, MsgContext) line: 307
  HandlerRequest.invoke(Msg, MsgContext) line: 385
  ChannelSocket.invoke(Msg, MsgContext) line: 748
  ChannelSocket.processConnection(MsgContext) line: 678
  SocketConnection.runIt(Object[]) line: 871

-
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



Change in StandardManager breaks SimpleTcpReplicationManager (TC5.5.9)

2005-06-22 Thread Eric Dalquist
There was a change in the StandardManager class for Tomcat 5.5.9 that 
deprecated the createSession method and created the 
createSession(sessionId) method to allow emptySessionPath=true to 
work. The SimpleTcpReplicationManager which subclasses StandardManager 
was not updated to reflect this change. Now if you try to use the 
SimpleTcpReplicationManager with the emptySessionPath=true 
configuration set the follow exception is thrown:


ERROR org.apache.catalina.cluster.session.SimpleTcpReplicationManager - 
[Unable to replicate session] 2005-06-22 13:13:42,657

java.lang.ClassCastException: org.apache.catalina.session.StandardSession
   at 
org.apache.catalina.cluster.session.SimpleTcpReplicationManager.requestCompleted(SimpleTcpReplicationManager.java:258)
   at 
org.apache.catalina.cluster.tcp.ReplicationValve.invoke(ReplicationValve.java:206)
   at 
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:105)
   at 
org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:107)
   at 
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:148)
   at 
org.apache.jk.server.JkCoyoteHandler.invoke(JkCoyoteHandler.java:307)
   at 
org.apache.jk.common.HandlerRequest.invoke(HandlerRequest.java:385)

   at org.apache.jk.common.ChannelSocket.invoke(ChannelSocket.java:748)
   at 
org.apache.jk.common.ChannelSocket.processConnection(ChannelSocket.java:678)
   at 
org.apache.jk.common.SocketConnection.runIt(ChannelSocket.java:871)
   at 
org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:684)

   at java.lang.Thread.run(Thread.java:595)

Doing some debugging it looks like Request.doGetSession(boolean) line: 
2204 calls public Session createSession(String sessionId); from the 
manager interface. Since SimpleTcpReplicationManager does not override 
this method but overrides the public Session createSession(); method 
the call goes directly into the StandardManager which returns a 
StandardSession. When the SimpleTcpReplicationManager attempts to 
replicate this session later it fails when trying to cast it to 
ReplicatedSession.


I've created a bug in bugzilla for the problem: 
http://issues.apache.org/bugzilla/show_bug.cgi?id=35473


I'm going to try and get a fix working locally but I've never tried to 
compile tomcat before. Any help would be much appreciated.


-Eric Dalquist

-
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]