Facilitating the Spread of Knowledge and Innovation in Professional Software Development

Write for InfoQ


Choose your language

InfoQ Homepage News A Real World Example of Using Terracotta: Clustering RIFE

A Real World Example of Using Terracotta: Clustering RIFE

This item in japanese

Terracotta's Jonas Bonér recently detailed how he and Geert Bevin (who was recently hired by Terracotta) clustered the RIFE web application framework. The article provides valuable insight into RIFE's continuations implementation as well as some of the challenges in clustering a non-trivial application like RIFE.

Bonér starts out by explaining how RIFE implements continuations:

RIFE’s continuations aims to make support for continuations in pure Java available as a general-purpose library ... It is using bytecode instrumentation (based on the ASM bytecode library) to generate code and redefine classes in order to implement this in the most effective way possible. It is not relying on Java serialization but is instead breaking down the object graph into primitives and stores the actual data on the execution stack (similar to the approach taken by Terracotta) ... The continuations are linked together in a tree structure which allows you to traverse to the different execution steps the way you want. This means that you can actually step back (and forward) in time, which is a very neat way of solving the browser back button problem - if used in the context of web applications.

Internally RIFE is storing its continuations in a regular java.util.HashMap.

The first obstacle they faced in clustering RIFE was to make access to this HashMap thread safe. The initial RIFE implementation was designed to only access the map using a thread for performance reasons. In moving to a clustered deployment there may be concurrent access from multiple JVM's.

The next challenged involved classloaders. As is typically the case with application servers and web frameworks, RIFE implements custom class loaders for a number of features which are not visible to Terracotta out of the box like the Java system class loader is:

The reason why Terracotta needs to be able to uniquely define a class loader is that it needs a way of, at any point in time and on an arbitrary cluster-node, retrieve the class loader instance that has loaded a specific class in order to maintain object identity across the cluster.

The biggest challenge Bonér and Bevin ran into however was clustering the dynamicity of the RIFE template engine. RIFE may generate classes on the fly at runtime if needed. This information needs to be replicated in the event that the node the class was created on crashes and subsequent request are redirected to another node. The solution proved to be a cluster wide bytecode repository implemented with a HashMap. The RIFE TemplateClassloader was then modified to reference this repository.

Rate this Article