You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by Eric Dalquist <ed...@unicon.net> on 2005/07/07 18:01:51 UTC

Tomcat Session Replication & Portlets

I have been working on getting session replication working with some web 
applications that use cross context dispatching. In this case it is 
uPortal and JSR-168 portlets running via the Jakarta Pluto portlet 
container.

Session replication is working as expected with uPortal. Portlets on the 
other hand are not having their sessions replicated. In this application 
configuration the follow calls are happening. The browser makes a 
request to tomcat for the uPortal web application. While uPortal is 
rendering it makes cross context dispatch calls to servlets in the 
portlet web applications to render the results in the portal's response.

After some digging and stack traces to figure out how session 
replication in tomcat is implemented I've determined why the portlet 
applications are not having their sessions replicated. It appears that 
there is a ReplicationValve which is enabled by the presence of the 
<Cluster> tag in Tomcat's server.xml. This valve is only present in the 
stack for a direct call to the container and is not present in a cross 
context dispatched call.

I would like to work with the Tomcat developers to implement the ability 
for cross context calls to also notify the session manager that 
replication should be considered for the context.

I am prepared to do the work for this task but would like to get some 
feed back from the tomcat developer community on recommendations and in 
what way the work could be done to ensure its eventual inclusion in the 
tomcat codebase.

Thank you,
   Eric Dalquist


Below are the stack traces I captures when looking into the issue.


The following is a stack trace of a request being made to uPortal. You 
can see the ReplicationValve class which the request is passing through 
7 items down.
Thread [TP-Processor3] (Suspended)
  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

After the portal completes servicing of the request the ReplicationValve 
performs the replication call 
(SimpleTcpReplicationManager.requestCompleted(String)) for the context.
Thread [TP-Processor3] (Suspended (breakpoint at line 242 in 
SimpleTcpReplicationManager))
  SimpleTcpReplicationManager.requestCompleted(String) line: 242
  ReplicationValve.invoke(Request, Response) line: 206
  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



The following is a request to uPortal that also interacts with a 
portlet. Looking far enough down the stack you see the base is the same 
as the first example stack. The 9th item down in the stack is the last 
uPortal class (CPortletAdapter) that gets used to call the portlet. The 
next 3 items are pluto classes that get the cross context request 
dispatcher and call it (ApplicationDispatcher.include(ServletRequest, 
ServletResponse) line: 499). The top of the stack is the last tomcat 
class that gets called before Pluto's PortletServlet gets executed.
Thread [TP-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: tomcat-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tomcat-dev-help@jakarta.apache.org


Re: Tomcat Session Replication & Portlets

Posted by Remy Maucherat <re...@apache.org>.
Peter Rossbach wrote:
> Hey Eric,
> 
> which tomcat release you use?  I have change a lot inside the current 
> 5.5 cvs head and hope your
> work is compatible with this changes. I thing your changes is not easy 
> and you must reflect that other
> Valves and Listener must also reflect your API deprecated CrossContext 
> feature. Why the Portlet API
> need CrossContext?

Because the portlet specification is stupid, and is 100% based on cross 
context, which is *the* non portable feature.

> Implementatation help: Your must rewrote the complete ReplicationValve 
> and JvmRouteBinderValve
> 
> Look inside ReplicationValve.invoke and get from Container the Cluster
> CatalinaCluster cluster = (CatalinaCluster) getContainer.getCluster();
> Currently you can get the complete list of the registerted application 
> managers....
> It is not easy to detected changes coordinate the startup and restart 
> manager phase.. ( Look inside DeltaManager :-)
> I thing you must coordinate your replication with other threads ... ( 
> very bad sync blocks....).

Since he's using portlets, he'll have to use emptySessionPath, which 
solves problems related with session ID handling.

I though there would be no big problem with keeping a list (thread 
local) of sessions which have been accessed during a request, and have 
the replication valve take care of them. Either that or the request 
dispatcher will have to integrate the functionality of the replication 
valve (to some extent; I suppose this means adding a callback or 
something on Cluster).

It's definitely not a piece of code to start on if someone doesn't know 
Tomcat well, that's for sure. Given the initial email, my advice is to 
forget about it for now and be a bit patient (or I'll just say happy 
hacking, but it's very unlikely I'll integrate any submitted changes).

Rémy

---------------------------------------------------------------------
To unsubscribe, e-mail: tomcat-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tomcat-dev-help@jakarta.apache.org


Re: Tomcat Session Replication & Portlets

Posted by Peter Rossbach <pr...@objektpark.de>.
Hey Eric,

which tomcat release you use?  I have change a lot inside the current 
5.5 cvs head and hope your
work is compatible with this changes. I thing your changes is not easy 
and you must reflect that other
Valves and Listener must also reflect your API deprecated CrossContext 
feature. Why the Portlet API
need CrossContext?

Implementatation help: Your must rewrote the complete ReplicationValve 
and JvmRouteBinderValve

Look inside ReplicationValve.invoke and get from Container the Cluster
CatalinaCluster cluster = (CatalinaCluster) getContainer.getCluster();
Currently you can get the complete list of the registerted application 
managers....
It is not easy to detected changes coordinate the startup and restart 
manager phase.. ( Look inside DeltaManager :-)
I thing you must coordinate your replication with other threads ... ( 
very bad sync blocks....).

have fun...
Peter







Eric Dalquist schrieb:

> I have been working on getting session replication working with some 
> web applications that use cross context dispatching. In this case it 
> is uPortal and JSR-168 portlets running via the Jakarta Pluto portlet 
> container.
>
> Session replication is working as expected with uPortal. Portlets on 
> the other hand are not having their sessions replicated. In this 
> application configuration the follow calls are happening. The browser 
> makes a request to tomcat for the uPortal web application. While 
> uPortal is rendering it makes cross context dispatch calls to servlets 
> in the portlet web applications to render the results in the portal's 
> response.
>
> After some digging and stack traces to figure out how session 
> replication in tomcat is implemented I've determined why the portlet 
> applications are not having their sessions replicated. It appears that 
> there is a ReplicationValve which is enabled by the presence of the 
> <Cluster> tag in Tomcat's server.xml. This valve is only present in 
> the stack for a direct call to the container and is not present in a 
> cross context dispatched call.
>
> I would like to work with the Tomcat developers to implement the 
> ability for cross context calls to also notify the session manager 
> that replication should be considered for the context.
>
> I am prepared to do the work for this task but would like to get some 
> feed back from the tomcat developer community on recommendations and 
> in what way the work could be done to ensure its eventual inclusion in 
> the tomcat codebase.
>
> Thank you,
>   Eric Dalquist
>


---------------------------------------------------------------------
To unsubscribe, e-mail: tomcat-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tomcat-dev-help@jakarta.apache.org


Re: Tomcat Session Replication & Portlets

Posted by Eric Dalquist <ed...@unicon.net>.
Rémy,
    We are hoping to get this work done in short order for a client. 
What class are the access / endAccess methods in?

Thank you,
-Eric Dalquist

Remy Maucherat wrote:

> Eric Dalquist wrote:
>
>> I am prepared to do the work for this task but would like to get some 
>> feed back from the tomcat developer community on recommendations and 
>> in what way the work could be done to ensure its eventual inclusion 
>> in the tomcat codebase.
>
>
> We're not going to need much help here, as I assume that there will be 
> at least two persons interested in fixing this eventually. Probably 
> registering sessions for checking in access or endAccess would be a 
> decent solution.
>
> Rémy
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: tomcat-dev-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: tomcat-dev-help@jakarta.apache.org
>
>

---------------------------------------------------------------------
To unsubscribe, e-mail: tomcat-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tomcat-dev-help@jakarta.apache.org


Re: Tomcat Session Replication & Portlets

Posted by Remy Maucherat <re...@apache.org>.
Eric Dalquist wrote:
> I am prepared to do the work for this task but would like to get some 
> feed back from the tomcat developer community on recommendations and in 
> what way the work could be done to ensure its eventual inclusion in the 
> tomcat codebase.

We're not going to need much help here, as I assume that there will be 
at least two persons interested in fixing this eventually. Probably 
registering sessions for checking in access or endAccess would be a 
decent solution.

Rémy

---------------------------------------------------------------------
To unsubscribe, e-mail: tomcat-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tomcat-dev-help@jakarta.apache.org