Monday, October 8, 2007

Readline setup in Jython on OSX

In the last blog post I neglected to state that I included enabling readline support in the startup script for Jython. to remove this comment out:

-Dpython.console=org.python.util.ReadlineConsole \
-Dpython.console.readlinelib=GnuReadline \

in tc-jython.sh.

If you want to enable readline support on OSX however download this file, unzip the file and move the 2 files into the /Library/Java/Extensions folder. Do not move the folder there just the 2 files that are contained by the folder. I did not compile these personally, unfortunately I lost the reference to the site that lead me to this epiphany.

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