Akka Futures In Scala With A Simple Example


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.

def timeTakingIdentityFunction(number: Int) = {
    // we sleep for 3 seconds and return number
    Thread.sleep(3000)
    number
  }

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.

object SumApplication extends App {
  val startTime = System.currentTimeMillis
  val number1 = timeTakingIdentityFunction(1)
  val number2 = timeTakingIdentityFunction(2)
  val number3 = timeTakingIdentityFunction(3)
  val sum = number1 + number2 + number3
  val elapsedTime = ((System.currentTimeMillis - startTime) / 1000.0)
  println("Sum of 1, 2 and 3 is " + sum + " calculated in " + elapsedTime + " seconds")

  def timeTakingIdentityFunction(number: Int) = {
    // we sleep for 3 seconds and return number
    Thread.sleep(3000)
    number
  }
}

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.

val timeTakingIdentityFunctionFuture = Future(timeTakingIdentityFunction(1))

Since we are making three calls on timeTakingIdentityFunction. We can collect Future[Int] in three variables i.e. future1, future2, future3

  val future1 = Future(timeTakingIdentityFunction(1))
  val future2 = Future(timeTakingIdentityFunction(2))
  val future3 = Future(timeTakingIdentityFunction(3))

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.

  val future = for {
    x <- future1
    y <- future2
    z <- future3
  } yield (x + y + z)

future onSuccess {
    case sum =>
      val elapsedTime = ((System.currentTimeMillis - startTime) / 1000.0)
      println("Sum of 1, 2 and 3 is " + sum + " calculated in " + elapsedTime + " seconds")
  }

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.

import akka.dispatch.Future
import akka.actor.ActorSystem

object SumApplicationWithFutures extends App {
  implicit val system = ActorSystem("future")
  val startTime = System.currentTimeMillis
  val future1 = Future(timeTakingIdentityFunction(1))
  val future2 = Future(timeTakingIdentityFunction(2))
  val future3 = Future(timeTakingIdentityFunction(3))

  val future = for {
    x <- future1
    y <- future2
    z <- future3
  } yield (x + y + z)

  future onSuccess {
    case sum =>
      val elapsedTime = ((System.currentTimeMillis - startTime) / 1000.0)
      println("Sum of 1, 2 and 3 is " + sum + " calculated in " + elapsedTime + " seconds")
  }

  def timeTakingIdentityFunction(number: Int) = {
    // we sleep for 3 seconds and return number
    Thread.sleep(3000)
    number
  }
}

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.

This entry was posted in Scala and tagged , . Bookmark the permalink.

13 Responses to Akka Futures In Scala With A Simple Example

  1. n3llyb0y says:

    Very succinct example of direct Future usage.
    Thanks for the post!

  2. Pingback: Akka Futures in Scala « Giovanni’s Blog

  3. Meetu Maltiar says:

    As suggested, this example can be conciser. Applying hint I gave, we can do the following:
    // we construct List[Future[Int]]
    val futureList = List(1, 2, 3) map { case number => Future(timeTakingIdentityFunction(number)) }
    // we compose from List[Future[Int]] to Future[List[Int]]
    val future = Future.sequence(futureList)
    // we wait on the combined Future[List[Int]] and print the result
    future onSuccess {
    case results =>
    val elapsedTime = ((System.currentTimeMillis – startTime) / 1000.0)
    println(“Sum of 1, 2 and 3 is ” + results.sum + ” calculated in ” + elapsedTime + ” seconds”)
    }

  4. Meetu,

    Thanks for putting this together.

    I’d like to mention that Akka Futures have been moved (after unification with some other Future implementations and standardization under the umbrella of SIP 14) to the Scala standard library in 2.10 and therefore there are no more Akka Futures in Akka 2.1.

    Another aspect I’d like to point out: If you compose Futures monadically, i.e. with a for expression, you will *sequence* them. Therefore the running time will be the sum of the individual running times. In other words, you don’t go parallel.

    If parallelism is what you want, you have to compose the individual Futures into one like shown in your earlier comment. Fun fact: Although the composite Future will execute all parts in parallel (real parallel only when there are enough threads/cores), the name of the composing operation is `sequence`.

    Heiko

    • Meetu Maltiar says:

      Thanks a lot Heiko,

      Yes we are going to use latest Akka version soon, we are still on Akka 2.0.5. I will bump it to the latest in our upcoming release. Thanks for pointing out that from 2.1 both scala and Akka has been combined. I will mention that in my post.

      For this simple example number of threads are available and we do get the three time benefit :). The major point is that if need be, we need not make blocking calls.

      As for composing futures we do get the benefit because we compose Future after we create them. If we had composed them without creating them then they would have run sequentially. For example the above code and in gist https://gist.github.com/4561789 and the one mentioned in blog https://gist.github.com/4562364 runs in three seconds instead of nine.

      Regards,
      Meetu

      • Meetu,

        You are right: You create the futures up-front which kicks them off immediately, of course. Composition comes afterwards.

        Good to see that you know that stuff very well ;-)

        Heiko

      • Meetu Maltiar says:

        Thanks a lot Heiko,
        We all are learning, and Akka is such a great toolkit. It did wonders to many applications we built. Thanks to you and your organization Typesafe for building this great toolkit and Scala.
        Kind regards,
        Meetu

  5. Pingback: Akka And Futures | Knoldus

  6. Pingback: Akka Futures: Using For Comprehensions | Knoldus

  7. Pingback: Knolx Session: Using Akka Futures | Knoldus

  8. Pingback: Scala Snippets « Stray Thoughts

  9. deepakcgaikwad says:

    One first needs to think in Scala and to understand Scala codes and examples. Your article is a good help for the starters.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s