All you need to know about development and direction

What’s new in Akka?

Roland Kuhn

Last year, Akka won the JAX Innovation Award for Most Innovative Open Source Tech—we’re still very proud of this recognition!—and one thing I can say is that winning the award did not make us pause or slow down. A lot is happening in and around Akka as we will see in this whirlwind tour through the ecosystem.

Before we begin, a personal note: On March 7 this year, Patrik Nordwall took over the Akka Tech Lead duties because I co-founded Actyx, a startup that helps small and mid-sized manufacturing companies to reap the benefits of digital technologies—sometimes classified as Industry 4.0. I remain very interested in Akka and I continue to develop some parts as we’ll see in this article, but I no longer speak for Lightbend.

The biggest development within Akka since 2.3.0 (March 2014) has for sure been the Reactive Streams [1] initiative and Akka Streams. The former is now slated for inclusion in Java 9 under the name Flow [2] and it forms the basis for the inner workings of the latter: Akka Streams is fully Reactive Streams-compliant. Streaming data pipelines are becoming ever more common and satisfy a rising demand of properly rate-controlled processing facilities—gone are the days of OutOfMemoryErrors resulting from one overwhelmed actor’s mailbox.

Streams were first developed on a very long-lived feature branch and versioned separately. Their experimental phase ended when they were released as part of Akka 2.4.2 in February 2016. In parallel, Spray—the lean and expressive HTTP library—has been rewritten on top of Akka Streams, a new foundation for reliable and efficient processing of large payloads. The resulting Akka HTTP modules present one of the most modern HTTP stacks available today, which is perfectly positioned for implementing the HTTP/2 standard that is swiftly gaining popularity: HTTP/2 connections are optimized for streaming several independent requests and responses at the same time. Konrad Malawski (maintainer of the Akka HTTP modules) and Johannes Rudolph (co-author of Spray and now member of the Akka core team at Lightbend) have started a proof-of-concept implementation for HTTP/2 support in September and I’m excited to see the results.

The 2.4.9 release has brought its performance up to the level of Spray or even beyond, and the Java and Scala APIs are merely being polished a bit more to straighten out a few remaining wrinkles. The surface area covered by an HTTP implementation as complete and expressive as this one is enormous: the user-facing API has more than 26,000 lines of Scala code, defining all those media types, encodings and other headers as well as the directives for routing requests and formulating responses. In order to allow more people to contribute efficiently—and in order to allow the HTTP modules to evolve at a faster pace than the very stable Akka core—the high-level HTTP modules are moving out of the core Akka repository into a separate new home under the Akka organization on GitHub. For more details see the 2.4.9 release notes and the discussion on the akka-meta repository [3].

Apropos contributions: since the addition of Streams & HTTP, we have seen a marked increase in the breadth of our contributor base. Every minor release contains the work of circa 40 community members. Contributing has never been easier, not only because the high-level features of Streams & HTTP are more accessible, I think it is also due to the use of Gitter for nearly all team communication.

There is also vivid exchange with authors of integration libraries that connect Akka Streams to data sources and sinks like message brokers, files, databases, etc. In order to foster this growing ecosystem, an umbrella project named Alpakka [4] has been created, similar in spirit but of course currently a lot less powerful than Apache Camel. Everyone is invited to think up and implement new integrations — this is your chance to give back to the community. These are currently best targeted at the Akka Stream Contrib repository, but the team is thinking about opening a special Alpakka dedicated repository as well.

Another project that will have deep impact on how you use Akka is going on under the hood and driven by the core team — its codename is Artery. This new remote messaging stack is based on the Aeron [5] library and on Akka Streams and delivers vastly improved throughput and latency for sending messages across the network—just be sure to not use Java Serialization, which is just too slow to keep up. The goal of this rewrite of the basis for clustering is not only improved performance, the main impetus behind it is to use the expressive power and safety of Streams to simplify the implementation and eventually provide verified cross-version stability and compatibility. The current status (as of Sep 19, 2016) is that milestone 4 is available for you to try out and give feedback on. [6] Within the next few months Artery will replace the old remoting implementation and become the default.

The last project to talk about is the one that I am deeply involved in. Akka Typed has been included since version 2.4.0 as a sketch of how to achieve type-safety in actor interactions in a fashion that is simple to understand, without compiler magic, and inherently built for great and easy test coverage. In a nutshell, it consists of a generic ActorRef that only accepts a certain well-specified type of messages, plus a generic Behavior (i.e. actor implementation) that only expects inputs of a given type. It is the third attempt in this direction within Akka and I firmly believe that this is the one that works. Recently, also due to the intention to use this at Actyx, I have created an entirely new implementation of the actor mechanics for the Akka Typed package, making it available alongside the adapter that offers the new features as an emulation layer on top of the untyped akka-actor package.

Based on the experience collected over the past six years from developing Akka, we decided to remove features that greatly complicate the internal code while not delivering sufficient benefit to all users. The full list has been discussed on akka-meta [7]; highlights are the configurability of mailboxes and remote deployment. Together with the relocation of the execution of supervisor strategies into the child actors themselves this has led to a huge reduction in code size, while the user-facing feature set has only been trimmed slightly.

Special focus has been devoted to pervasive testability, both of the implementation and of user-level code. The main difference to untyped actors in this regard is that behavior and execution are fully decoupled now, you can create your actor behaviors directly within tests and exercise them synchronously without using a special TestActorRef or CallingThreadDispatcher. This allows convenient validation of internal logic as well as deterministic stimulation with external inputs. A mock ActorContext can be used to check that child actors are created correctly, all other effects like watching/unwatching are accessible as well.

The new implementation is quite a bit faster than the old one, reducing actor messaging overhead by 20–30 percent even though the mailbox implementation is not yet optimized. Once the full potential has been realized, it will be possible to achieve allocation-free actor messaging. The current breadth of the implementation covers only local actors without persistence, the plan is to add a custom Materializer for Akka Streams and reuse Artery in order to have a new basis for the existing clustering code.

One aspect that I find extremely exciting about Akka Typed is that it opens up actor interactions to even more static verification than is afforded by a type-selective ActorRef. Current research within the ABCD group [8] has the potential to enable an actor-based implementation of a verified communication protocol to be checked for conformance to the specification by the Scala compiler (here it might be that Java’s type system is not expressive enough to achieve the full feature set). This would mean that many bugs would be caught without even running a single test, the compiler will tell you that you forgot to send a certain message or that you expected to receive a message that will never arrive.

Enabling the compiler to see these actions means representing them in the type-system and lifting the description of what an actor does into a sequence of actions that can be inspected. This is a powerful tool even without the protocol verification, it allows actor behaviors to be composed in ways that were very cumbersome or impossible before. Think about an actor that speaks some protocol with its clients, in the simplest case request–response. In order to compute the response the actor might have to converse with a handful of other actors in a multi-message exchange. Previously you would implement that by manually stashing all unexpected messages and switching between different behaviors using context.become(). With the upcoming Akka Typed DSL [9] it becomes possible to write down a sequence of send and receive actions using a Process abstraction, where processes can be composed to run in sequence or in parallel within the same actor. This greatly simplifies the code structure because it disentangles the different aspects of an actor’s behavior and sorts them into cohesive strands that each fulfill their separate purposes.

All this is currently still in the research phase, so feedback is very much welcome and needed to get it ready soon.

Oh, and one last thing: at Actyx we are currently working on an improved version of distributed data structures (for the curious: an implementation of δCRDTs) that can be used independently of Akka Cluster. If that turns out to be successful, we will open-source this as a cousin to Akka Distributed Data.

ReactiveTo read more about reactive programming, download the latest issue of JAX Magazine:

Reactive programming means different things to different people and we are not trying to reinvent the wheel or define this concept. Instead, we are allowing our authors to prove how Scala, Lagom, Spark, Akka and Play coexist and work together to create a reactive universe.

If the definition “stream of events” does not satisfy your thirst for knowledge, get ready to find out what reactive programming means to our experts in Scala, Lagom, Spark, Akka and Play. Plus, we talked to Scala creator Martin Odersky about the impending Scala 2.12, the current state of this programming language and the technical innovations that await us.

Thirsty for more? Open the magazine and see what we have prepared for you.

Roland Kuhn
Dr. Roland Kuhn is CTO and co-founder of Actyx, author of Reactive Design Patterns, a co-author of the Reactive Manifesto, co-teacher of the Coursera course “Principles of Reactive Programming”, and a passionate open-source hakker. Previously he led the Akka project at Lightbend.

comments powered by Disqus