Monday, October 8, 2007

Jython Clustering Interface

In our last installment I attempted to cluster the entire Jython interpreter. This failed due to the lack of support of WeakReferences, Interned Strings and likely other JVM specific items. In this installment I create a way to interact with the Terracotta DSO cluster from an API within Jython.

Much of this is a simple port with Jython style semantics from Jonas Bonér's blog entry, JRuby with Terracotta. One thing to notice about Jonas' implementation of clustering with Jruby is that he uses anonymous blocks, a feature that Ruby has that Python has yet to embrace, so the API needed to make this clustering will be a little different. We will be a little more verbose in our translation of:

lock target
  transaction begin
    modify target
  transaction commit
unlock target

Rather than:

guard @messages do
  @messages.add msg
end

We will have to do something like the following:

try:
  guard(messages)
  messages.add(msg)
finally:
  endGuard(messages)

This is due simply to the fact that there is a hidden assumption in the implementation of guard where it accepts an anonymous block and wraps it with the equivalent to a try/finally block in python. In the attached file chatter.py the only lines dealing with Terracotta are the ones adding transaction boundaries to the addition of an ArrayList:

-->  DSO.guard(messages)
     messages.add("[#"+time.asctime()+" "+name+"] "+text)
-->  DSO.endGuard(messages)

And the following line to set up the shared root:

  messages=DSO.lookupOrCreateRoot("myRoot", messages)

It also appears that since Jonas wrote his article on how to cluster JRuby, the requirements for the startup have changed slightly. The following line is required to fire up a jython interpreter that can talk to a Terracotta cluster:

java -Xbootclasspath/p:$BOOTJAR \
  -Dtc.config=$JYTHON_INSTALL_DIR/tc-config.xml \
  -Dtc.install-root=$TC_INSTALL_DIR \
  -Dpython.console=org.python.util.ReadlineConsole\
  -Dpython.console.readlinelib=GnuReadline \
  -cp \ $JYTHON_INSTALL_DIR/jython.jar:\
$TC_INSTALL_DIR/lib/tc.jar org.python.util.jython chatter.py


Where $BOOTJAR is the location of your Terracotta boot.jar file.

Files of interest:
tc-jython.sh
DSO.py
chatter.py

2 comments:

grignaak said...

(a year and a half later...)

You know, in python 2.5+ you can use the with statement to create a guard:

with gaurd(messages):
messages.add(msg)

Ben Kearns said...

Thanks for the insight. This interface was more of a proof of concept than anything else.

Soon after this blog post I started playing around a with Clojure and also started neglecting my blog. Thanks also for the reminder that people really are readign the internet.

If you're interested there is a proof of concept of Clojure working on Terracotta where they fixed many of the issues that I ran into with this initial proof of concept. I have not investigated if any of the techniques that they used to get the symbols replicated would be applicable to Jython.