Couple of times already I’ve found myself in a situation that I wanted to prototype something based on Akka Cluster. In order to do that I was almost always reviewing the Akka Cluster Usage Sample and downloading the sample, or have used one of my already created examples. The problem with that approach is that all of the samples already have code and configuration in it. Mostly, with new prototypes, I don’t need package names, configurations and snippets of code remaning from other prototypes..
So this time, when I wanted to prototype an actor based PubSub dispatching mechanism on Akka Cluster, I decided to finally extract a template for that, so it doesn’t take half an hour to get a cluster running locally.
Giter8 templates
There’s a nice project called Giter8 created exactly for such cases. I’ve stumbled upon it already some years ago. But never had the chance/need to actually create a template myself. So.. I started :).
Akka Cluster base project
For my new scaffold/template project I had minimal requirements:
project has to be akka cluster based
akka cluster should be configured right from the start, so that no code change is required to setup a working cluster
it has to start the cluster locally, thus enabling prototyping really fast without the need for extra configuration
Enabling Akka Cluster
This is quite easy to achieve, proper library dependencies have to be added to the project:
Additionally I’ve already added logging component, as it comes quite handy with my logback configuration I use almost everywhere.
Making sure Akka Cluster is configured
That’s also mostly quite easy, as Akka Cluster Documentation describes it quite good. But nevertheless some configuration is needed:
Starting the cluster locally
Starting multiple actor systems locally, that form a cluster is also trivial (it’s also shown somewhere in the Akka Cluster Example). How it’s basically achieved? Well, in one JVM (one main method) multiple akka nodes are being started, which join the cluster (due to the shared configuration, pointing to local seed nodes). The imported main parts of such project:
ExampleClusterApp.scala - is the wrapper main App starting multiple applications:
ExampleApp.scala - is the actuall main App starting the Akka Cluster:
.parseString(s"akka.remote.netty.tcp.port=$port") - substitutes the Akka Remoting port with provided value
build.sbt - making sure that run invokes the wrapper App:
application.conf - couple of helping settings:
akka.remote.netty.tcp.port = 0 - would be random by default, but gets overriden anyway
akka.cluster.jmx.multi-mbeans-in-same-jvm - informs Akka, that there are multiple clusters in one JVM
ClusterListener.scala - also taken from the Akka Cluster Example to see/notify about the cluster events:
And that was all there is to the simple Akka Cluster App. Now it needs to be made available as a Giter8 template.
Gitering the solution
The documentation available at http://www.foundweekends.org/giter8/template.html describes quite well, how such templates are supposed to be created. In this case I’ll just limit myself to show the g8 project structure and list some gotchas I’ve came across.
Giter8 default.properties:
This file will be used, as configuration, by Giter8 during the scaffold/generation process. The variables are being then used for substitution in the project template.
Project directory structure:
all of template project files, by convention, should be placed either into src/main/g8 or ./ directory.
the default.properties files contains variables which will be substituted during project scaffolding/generation;
$package$ - will be expanded into directories defined by the package name
$classname$ - name of classes, coming directly from the project name - that is sufficient for the fast prototyping needs
inside default.properties file default values are residing, so that it’s not needed to provide them at all
One of the source files:
Gotchas:
I had issues while trying to use Scala string interpolation like this s"$variable" - the Giter8 processor (because of $) tried to use $variable as something to replace; I fixed the issue by switching to "" + variable notation; not really sophisticated, but does the job ;); I did not search for a solution though
verbatim=*.xml was added becasue the logback.xml file contains a ${CONSOLE_LOG_PATTERN} entry, which again is not parsed by Giter8 properly
Example run
Now it is really easy to scaffold a basic, working Akka Cluster application by simply executing sbt:
Since a picture is worth more, than tousands of words:
Enhancements
I already have some ideas of what I could change and benefit from it:
adding Revolver Plugin for sbt, so that sbt doesn’t get blocked by the running nodes
adding Docker/Docker Swarm template for deploying locally
adding Kubernetes template, for deploying to a locally running Minikube cluster