Date: 2005-01-14T00:23:50
   Editor: ReinhardPoetz
   Wiki: Cocoon Wiki
   Page: FlowscriptAndSessionReplication
   URL: http://wiki.apache.org/cocoon/FlowscriptAndSessionReplication

   no comment

New Page:

= Goal =

 * make session replication work with Flowscript

= Background =
Cocoon uses Mozilla Rhino for its Flowscript implementation. Looking into a 
Cocoon sitemap reveals that flowscripts are  registered in

{{{
<map:flow language="javascript">
  <map:script src="flow.js"/>
  <map:script src="flow1.js"/>
</map:flow>
}}}

For every sitemap a scope (A scope is a set of JavaScript objects. Execution of 
scripts requires a scope for top-level script variable storage as well as a 
place to find standard objects like Function and Object - find more at 
http://www.mozilla.org/rhino/scopes.html) that is put into the users session.

Additionally to the scope, Cocoon has to manage all continuations that are 
created while executing the functions of the flowscript. Since Cocoon 2.1.6, 
these continuations can be stored in the Session too (its configurable in 
cocoon.xconf).

{{{
 +-------------------------+
 |SESSION1                 |
 |+-----------------------+|
 ||scope (sitemap A)      ||
 |+-----------------------+|
 |+-----------------------+|
 ||scope (sitemap B)      ||
 |+-----------------------+|
 |+-----------------------+|
 ||scope (sitemap C)      ||
 |+-----------------------+|
 |+-----------------------+|
 ||ContinuationsHolder    ||
 ||(all continuations of  ||
 || this user)            ||
 ||                       ||
 ++-----------------------++
 |+-----------------------+|
 ||other session attr.    ||
 ||                       ||
 ||                       ||
 ||                       ||
 |+-----------------------+|
 +-------------------------+
}}}

= What's the problem? =

== Serializable objects ==
=== Description ===
To enable session replication between two application servers (e.g. Tocmat, see 
http://jakarta.apache.org/tomcat/tomcat-5.5-doc/cluster-howto.html) you have to 
make sure that all session attributes are serializable (implement 
{{{java.io.Serializable}}}).

Unfortunatly this wouldn't work for Cocoon because of two problems:

 * As the  scope has references to many Cocoon internal objects (see the Cocoon 
object) serialization wouldn't work because many of them are not serializable
 * Serializing all the large objects would be very expensive
 
=== Possible way to solve this problem? ===
(outlined by Christopher Oliver)

I think the first thing you need to do is determine exactly what needs to be 
serialized into the replicated session. A given Rhino global scope object can 
contain a lot of references to Java objects that may not be serializable or it 
may not be desirable to serialize them.

All such objects need to be identified and "replaced" with something else in 
the serialization stream. You can override the replaceObject() and 
resolveObject() methods of ObjectOutputStream and ObjectInputStream to 
implement this. When the stream is deserialized you can then substitute 
suitable replacement objects from the target JVM. See the 
org.mozilla.javascript.serialize package in the Rhino distro for an example of 
this strategy.

Since the FOM objects refer to underlying Cocoon objects that should not be 
serialized (the session itself, the source resolver, etc) the above strategy 
would at least need to applied to them.  In addition, objects created by the 
user that are referenced via the Rhino global scope or the local variables of a 
continuation may need this treatment. 

== Plugging in the solution into existing containers ==
=== Description ===
The serialization/deserialization process of Java objects has to be overriden 
(see explanations by Chris). This mechanism has to be plugged into the 
container without having to modify it.

=== Possible soluation ===
 * Override the methods {{{writeReplace}}} and {{{readResolve}}} of the 
{{{ContinuationsHolder}}} and of the Javascript scope. This will require a 
wrapper object for the scope.
 * Write own implementation of {{{ObjectInputStream}}} and 
{{{ObjectOutputStream}}} that are used by the container as default.

== Delta management ==
=== Description ===
Exchanging e.g. the {{{ContinuationsHolder}}} because only one Continuation has 
been added, would be very expensive.

=== Possible solution ===
Add some kind of delta management into the serialization/deserialization 
process. But how ...?

Reply via email to