Helma logo
helma.org » Home > Stories > GroupExtension

GroupExtension

A Helma extension that puts several helma servers into a group and makes them share data in their memory over the network.

This package enables group-communication between different Helma Servers over the network taking advantage of JavaGroups Library (www.javagroups.com). A new global object group is added to the scripting environment and all changes in that object tree are immediately replicated to all members.


Helma prerequistes

A helma snapshot no earlier than August 2002 is required. Get the latest build from helma.org. If you are still running the pre3-package you need to add two further libraries to the classpath, download them straight from the cvs: jetty.jar, servlet.jar.

Installation

Download the current version of HelmaGroups.

Unzip the distribution to your Helma home directory. A new subdirectory helmagroups will be created. For running and testing there are two possiblities:

  • Run the startscripts in the helmagroups-directory. They use the libraries of the main Helma installation and just need a valid JAVA_HOME directive at the top of the startscripts. I've included several startscripts so that you can test two instances of Helma on the same machine but on different port numbers. This way you can run the demo applications grouptest and benchmark.
  • Change the following files in your installation:

    add to start.sh:
    export JARS=$JARS:helmagroups/helmagroups.jar
    export JARS=$JARS:helmagroups/javagroups-all.jar

    add to start.bat:
    set JARS=%JARS%;helmagroups\helmagroups.jar
    set JARS=%JARS%;helmagroups\javagroups-all.jar

Configuration

Update the configuration of your helma installation and add the following properties to the server.properties file. Examples are listed in helmagroups/server.properties.

extensions = helma.extensions.helmagroups.GroupExtension
This makes Helma load the extension at startup and add the group-object to every application on this server.

group = multicast | tcp | custom
Specify the type of network configuration group members use to communicate. For LANs multicast is the way to go, if multicast isn't available in your network ask your administrator. To test if multicast is configured correctly in your network and on your machine run the scripts in helmagroups/test. Strings that are typed into the console of a mcast-sender should appear on consoles running mcast-receiver.

group.multicast_ip = 224.0.0.150
group.multicast_port = 8090
group.multicast_ttl = 32

If you choose multicast the multicast_ip and multicast_port properties specify to which address the group is listening and sending. This has to be the same for all members of the group. multicast_ttl specifies how many hops a packet will travel on the network (time-to-live). If set to 0 packets are only received on the local machine.

group.tcp_hosts = 127.0.0.1, 192.168.0.1, ...
group.tcp_port = 8090
group.tcp_portrange = 4

If you choose tcp these properties specify the hosts that belong to this group and the port on which they are listening. As there could be more than one instance running on the same host, the tcp_portrange property specifies how many ports are tried above tcp_port.

group.custom = UDP(mcast_addr=224.0.0......
Basically JavaGroups is configured with a long properties string which is created by Helma when multicast and tcp configurations are provided. For debugging purposes the whole configuration string can be specified here. Documentation for custom configuration may be found at www.javagroups.com and in the source code of JavaGroups.

group.debug = props-file
Specifies the file containing the debug-configuration for JavaGroups, an example is in helmagroups/groupdebug.properties. If this file can't be found or the property value is simply "true" the JavaGroups stack won't do any debugging but Helma will still give some debugging output to the server log.

group.name = theNameOfTheHelmaGroup
Different groups of servers may run on the same network interface but can still be separated by using different groupnames.

Usage in the scripting environment

Basically, a new global object group is added to the scripting environment (like app or root etc). Below this object a tree of objects can be built, with all add-, modify- and remove-operations being transmitted to the network and replicated to all other helma servers in that group immediately. The JavaGroups-library takes care of transmitting these operations lossless, ordered and obtains the correct state during startup.

The group object is visible in all applications in the group. To this object new GroupObjects can be added. A GroupObject can have strings, numbers, dateobjects and other GroupObjects as properties, so a tree of GroupObjects and data can be built.

group.test = new GroupObject();
group.test.somekey = "some value";
group.test.propkey1 = new GroupObject();
group.test.propkey1.anotherkey = "another value";

As soon as a GroupObject is assigning to the tree, it can be seen by all other members of the group. From that point on, any change of a property will be replicated immediately to all other members. Please note that a change operation will block until it has been seen by all group members. So the above code would produce three updates of the group, better would be the following code:

var obj = new GroupObject();
obj.somekey1 = "somevalue1";
obj.somekey2 = "somevalue2";
group.test = obj; < now the whole object gets replicated

Unfortunately it's currently not possible to build a tree locally and then replicate all the objects.

Methods of a GroupObject

GroupObject.list()
returns an array containing all the properties that are GroupObjects.

var arr = group.test.listChildren();

GroupObject.count()
Returns the number of properties that are GroupObjects.

GroupObject.waitFor(propName, x)
Waits for x millis and stops if a property propName is touched in the meantime (added/modified,removed). Can be used for example to wait until a login-server has logged a user in and returned its data to the tree.

GroupObject.unwrap(), GroupObject.wrap()
Returns a local copy of a replicated GroupObject, with just the primitive properties (but not the children) copied. This can be used to save network load if more than one property is changed in a row: Unwrap() the object, do all the changes and put it back in the tree by using the wrap() method. It is important to go this way and not just assigning it to the original position because otherwise the branch that existed below that point would get lost.

var obj = group.test.unwrap();
obj.key1 = "value1";
obj.key2 = "value2";
group.test.wrap(obj);

Please note that transactions are NOT supported, so if the script fails later in the execution changes that were made to replicated objects will remain.


The root GroupObject has a few additional methods that deal with the whole group:

group.print(optional: filename)
group.printFull(optional: filename)

Dumps the structure of the tree (print) or the full content of the tree (printFull) to a string or to a file (if a filename is given as an argument).

group.countElements()
Returns the total number of GroupObjects in the group.

group.connect()
group.reconnect()
group.disconnect()

Remove or add the server from/to the group. Connect() is done at startup automatically.


group.getMembers()
Returns an array of strings denoting the members of the group (servername:port).



Page last modified on 2006-10-19 02:59 by czv