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 ...?