Concurrency and distributed systems are probably among the hardest parts of software engineering. Basic Java EE apps usually don’t need to deal with these issues that much, but increasing parallel computing resources in servers and constantly open client-server connections, like WebSockets, bring these problems closer to web app developers as well.
Although average web developers don’t that often need to fight with these hard “academic” problems, there are some areas of engineering where the problems of concurrency, distributed systems and their reliability play possibly the most important role. In e.g. telecom, nodes must be working tightly together, but one failing node can’t take the whole system down. New nodes and roles must be pluggable to a live system and it must even be able to heal itself from malfunctions automatically.
Built-in concurrency helpers in Java have been improving in almost every major release, but building non-trivial concurrent systems right is still a difficult task. Akka is a framework that tries to make solving these problems easier. Its so-called “actor model” adds some limitations and clear borders for execution units.
An actor can be seen as protected zone, in which its execution is always “thread safe”. For external communication, independently of the actors actual implementation, there is only one standard API: tell(message, sender)
. So, you can send a (serializable) message to it and that’s it. Implementing actors is then by no surprise just handling these messages. The actor system works as “a message bus” and orchestrator for well decoupled actors.
Although some might say the actor model limits their possibilities as a developer, it is a proven way to safely solve these overly complex problems. In the same way that Vaadin helps in web development, Akka helps in concurrency and distributed systems: it sets developers free to solve the actual domain problems.
Creating Vaadin UI to an Akka actor system
Akka is a JVM based system, with both Java and Scala APIs, so the task is in theory super easy. But, there is the concurrency part that you don’t want to fail. There are two places where a developer could possibly fail with the concurrency: sending messages to the Akka system and receiving messages from there.
From Vaadin to Akka is actually pretty bullet proof, no matter how you do it. Due to Akka’s model, you just can’t do it wrong here and Vaadin adds no extra complexity here. Sending a string “hello” to an actor might look like this:
actor.tell("hello", ActorRef.noSender());
The bit trickier part is getting the information back from the actor system into Vaadin UI. If the actor is expected to answer soon to your message, the simplest method is to use “ask pattern”. The helper will return a Future containing the possible answer:
button.addClickListener(event -> { Future<Object> f = Patterns.ask(actorRef, "message", 1000); // 1000 ms timeout Object answer = f.value(); });
You could also achieve similar results using a helper called Inbox. These solutions are also bullet proof in terms of concurrency. The whole execution of telling, waiting for an answer and updating the UI is from a user initiated thread. But in case getting the response from the system takes long, we’d definitely not want to block the UI waiting for the response. We’d need some sort of asynchronous communication with the Akka actor system.
In the example app I recently built, there is a slightly more sophisticated example suitable for receiving data from the system outside user interaction cycle. In the Reactive Stock example, the actor system produces random stock prices that we want to report to our layer UI eagerly. For each Vaadin UI instance, we create a special actor that registers itself to listen to selected stock symbols and that passes updates to its UI instance.
This kind of integration is finally something that can go wrong. As changes are now originated from a thread that is not initiated by user interaction, Vaadin can by no means do proper synchronization for the changes. Thus, all changes to the referenced UI must now be done with an explicitly locked session. The UI class has a handy helper method to which you can pass your changes as a standard Runnable instance. Vaadin then takes care of doing synchronization. In the example I did, this Vaadin specific “trick” is in a public UI method that is called by the UIActor. Here a clean Java 8 style Runnable is created with lambda expression:
public void updateStockDetails(String stockSymbol, StockQuote... values) { access(() -> { // YOUR MAGIC HERE } }
The full example is available via TypeSafe Activator and also via GitHub as a Maven build project so you should get started with it easily in your favourite IDE. Play with it for a while and you are ready to impress your company’s concurrency gurus with a clean cool RIA UI built with plain Java!