Sunday, June 21, 2009

Terracotta Cluster Events: A simple example

My friend instant messaging me this weekend about this app he is writing using Terracotta. He is concerned about when a node leaves/joins and terracotta cluster and was doing some really weird stuff with the JVM Shutdown hook. I decided to do a quick blog post about Terracotta Clustered Events which is a simple way for an app to listen for terracotta cluster wide events.

So first i'll generate a new project using the pojo-archetype:


mvn org.apache.maven.plugins:maven-archetype-plugin:2.0-alpha-5:generate \
-DarchetypeGroupId=org.terracotta.maven.archetypes \
-DarchetypeArtifactId=pojo-archetype \
-DarchetypeVersion=1.5.0-SNAPSHOT \
-DgroupId=org.terracotta.examples \
-DartifactId=clusteredapi-examples \
-Dversion=1.0.0 \
-DremoteRepositories=http://www.terracotta.org/download/reflector/maven2


The the following prompt appears:


[INFO] Scanning for projects...
[INFO] ------------------------------------------------------------------------
[INFO] Building Maven Default Project
[INFO] task-segment: [org.apache.maven.plugins:maven-archetype-plugin:2.0-alpha-5-parent-patch-SNAPSHOT:generate] (aggregator-style)
[INFO] ------------------------------------------------------------------------
[INFO] Preparing archetype:generate
[INFO] No goals needed for project - skipping
[INFO] Setting property: classpath.resource.loader.class => 'org.codehaus.plexus.velocity.ContextClassLoaderResourceLoader'.
[INFO] Setting property: velocimacro.messages.on => 'false'.
[INFO] Setting property: resource.loader => 'classpath'.
[INFO] Setting property: resource.manager.logwhenfound => 'false'.
[INFO] [archetype:generate]
[INFO] Generating project in Interactive mode
[INFO] Archetype repository missing. Using the one from [org.terracotta.maven.archetypes:pojo-archetype:1.5.0-SNAPSHOT] found in catalog local
[INFO] Using property: groupId = org.terracotta.examples
[INFO] Using property: artifactId = clusterapi-example
[INFO] Using property: version = 1.0.0
[INFO] Using property: package = org.terracotta.examples
Define value for property 'description': :


Now enter in a description, I typed in "This is an example project to demonstrate java clustered api" and then was prompted again and Typed in "Y"
Now we have a project to test out terracotta clustered api.

The clustered event api interfaces are available from the terracotta api jar, let's include that in our pom.xml


<dependency>
<groupid> org.terracotta.api</groupid>
<artifactid>api</artifactid>
<version>1.0.0</version>
</dependency>

Change the process class to have a count of 4, so we run 4 nodes from our tests.


<plugin>
...
<processes>
<process nodename="app" count="4" jvmargs="-Xmx20m">
<classname>org.terracotta.examples.App
</classname>
</process>
</processes>
</plugin>



Now that we have our app I want it to be clustered aware. In this example, I'm not going to do anything interesting except print out when node's joins and leaves. So I added the following listener and implementation to my existing App class:



public class App implements DsoClusterListener {

@InjectedDsoInstance
private DsoCluster cluster;

public void registerListener() {
this.cluster.addClusterListener(this);

}

...
public void nodeJoined(DsoClusterEvent dsoclusterevent) {
System.out.println("nodeJoined Event about node: " + dsoclusterevent.getNode());
}

public void nodeLeft(DsoClusterEvent dsoclusterevent) {
System.out.println("nodeLeft Event about node: " + dsoclusterevent.getNode());
}

public void operationsDisabled(DsoClusterEvent dsoclusterevent) {
//;
}

public void operationsEnabled(DsoClusterEvent dsoclusterevent) {
//
}


And then call registerListener from the main() function:


App app = new App();
app.registerListener();
app.addMessage("Hello, world");


now run the app with the following command to see the node events


mvn clean install
mvn tc:run


Much much more simpler then registering ShutDown hooks. The project is here

No comments: