We use Akka Futures extensively for a product built to handle huge load of streaming data. We have been early adopters of Akka and been using it right from its Akka 1.1.X days. We found Futures as simple yet powerful tool to add concurrent behavior in our application.
This post emphasizes importance of Akka Futures with a short and easy to understand example application. Please read excellent documentation on Akka Futures for more details.
Ok, now lets look at a simple example. Lets say we have an identity function. We sleep in it for a while to replicate long running nature. Here is the Scala code for the method.
Suppose, we have an application in which we call timeTakingIdentityFunction method three times, gather their return in three variables and execute sum on them. Here is the code listing.
When we run this we will get around nine seconds to execute it. But what will happen when we do not block on timeTakingIdentityFunction?
Using Akka Futures we can do exactly that. When we do not block on timeTakingIdentityFunction and continue processing, we get performance boost. Now lets look at the Akka Futures version.
We can use Future directly, we wrap method call in a Future. In our example, we can do this in code.
Since we are making three calls on timeTakingIdentityFunction. We can collect Future[Int] in three variables i.e. future1, future2, future3
Futures are monadic. We can compose them using for expressions. The future obtained by composing them can be used for calculating sum.
We will use onSuccess callback for this. Here is the code snippet.
We composed a new Future out of three. The new composed Future is of type Future[Int]. We issued a callback to gather sum of three numbers. Here is the complete example.
Only thing we have added here is implicit ActorSystem. Future requires an execution context. If ActorSystem is in implicit scope we are fine.
When we run Future version of the application it runs in about three seconds!!
Akka Futures can add benefit by adding concurrency in our applications. For example we might need to make three blocking Rest API calls to achieve a functionality. Depending on our use case we can avoid issuing blocking calls, but rather use Futures.
We used Futures directly in our example application. Since Futures are monadic we composed them using for expressions. We also used callback method to collect the result. And using them we got three times improvement in our code. Most importantly code is simple, concise and expressive.
There is more concise way to do this. We can construct List of Future[Int] and call Future.sequence to create or compose a single Future of List[Int]. Code is left as an exercise 🙂
Latest version of Akka 2.1.0 for Scala 2.10 has unified version of Future in Scala. This post pertains to Akka 2.0.5 version, concepts are still the same.