The project I currently work in is a Service Oriented Architecture (SOA) based system for the Finnish National Board of Education. The system is responsible for the whole joint application period in which (at the moment) all secondary education can be applied for. Our team is responsible for the actual calculation of points for each applicant and the final layout of students for each school.
In order to make a difference between applicants there is a set of formulas for each school that score applicants based on different rules. These formulas are modelled as a tree of functions, in which the number of branches, the number of nodes and the depth of the tree is unlimited. The actual calculation of each application is implemented as a separate Scala module, which is both fast enough and forced to execute the operation incrementally. However, these function trees are also exposed for the modelling interface through a REST API implemented with Java, Spring, and JAX-RS. Each function in the tree is a complex object with multiple relations to other objects. The tree needs to be fetched and constructed in a single recursive loop that started to take tens of seconds to complete for the most complex formulas. I wanted to make this operation faster by processing each branch and node concurrently.
Before joining Gofore last autumn, I had developed almost entirely with Scala for at least a year. As a Scala developer, I was of course familiar with the awesome Akka library, which is
”a toolkit and runtime for building highly concurrent, distributed, and fault tolerant event-driven applications on the JVM.”
Simply put, it enables and simplifies the development of Reactive Applications with Actors. Actors are small entities with mailboxes that run concurrently and communicate with each other through asynchronous messaging. The actor model is a powerful and easy to understand abstraction for both concurrency and asynchronous messaging. Akka has bindings for both Scala and Java with very few (if any) fundamental differences and if you know one you know both. If you are interested in more detailed introduction to Akka and the Actor model you could check out for example this blog post.
I knew that with Akka I could develop the concurrent implementation, but I had zero understanding on how well Akka and Spring would play together. At first I gave it shot by myself, which lead to a series of epic failures. Fortunately, I found this great Typesafe Activator template that included a configuration file for setting up an Actor system aware of Spring’s Application Context. With the help of the template (and now knowing that when running tests with HSQDB and Akka you should set the database transaction control to MVCC) everything has worked smoothly and much faster. Unfortunately, I didn’t run any specific tests to measure the exact improvement gain from the concurrent processing, but at least now the slowest tree construction takes well under ten seconds meaning that the most complex formulas take many hundred percents less time to construct.
Below is a simplified example of one of our services and actors. There is a method in the service layer (getFunctionRecursively) which takes an ID of the root node in the function tree, fires up the Actor System, creates the master actor and asks the master to construct the formula.
The actual Actor is quite simple. The receive method is mostly interested in messages with the type of Recursion or Function. When it receives a Recursion message it will fetch the current tree’s (or subtree’s) root Function and starts to construct its subtrees by spawning a new Actor for each of nodes. If the actor receives a Function message it knows that it’s from one of the child actors and adds the function to the set of constructed children. Finally the root actor responds with the fully constructed formula to the method in the service layer.
As a developer familiar with Scala, I wasn’t surprised of how well and easily the actors worked. I wasn’t even that amazed for the simplicity of concurrent programming since Scala has many relatively easy ways for getting it done. However, in the Javaland it is usually a much harder thing (Java 8 will help to some degree) and for that reason I advise all of you Java developers to take Akka for a spin.
Side note: I recently heard about a framework called Reactor which share some commonalities with Akka. It would be nice to test it as well.