Using Akka futures
Akka Futures definition: A Future is a data structure used to retrieve of some concurrentoperationThis operation is performed by an Actor or a dispatcher directly result can be accessed synchronously or asynchronously.
QCon London: Mastering long-running processes in modern architectures
Using Akka Futures
1. Using Akka Futures
Meetu Maltiar
Principal Consultant
Email: meetu@knoldus.com
Twitter:@meetumaltiar
2. SIP 14
There were eight different Future
implementations:
java.util.concurrent.Future akka.dispatch.Future
scala.actors.Future scalaz.concurrent.Promise
scala.parallel.Future net.liftweb.actor.LAFuture
com.twitter.util.Future ...sff4s
3. Define Them
Future and Promise are tied to each other.
But they are different!
A Future is a read-handle to a single value
that may be available in a specific time
frame.
A Promise is a write-handle to a single
value (write-once) that should be made
available in a specific time-frame.
4. Akka Futures definition
A Future is a data structure
Used to retrieve of some concurrent
operation
This operation is performed by an Actor or a
dispatcher directly
The result can be accessed synchronously or
asynchronously
5. Future has States
A Future has three states. Initially it does not
have anything, later can be a success or a
failure.
Pending => Success / Failure
6. Execution Context
Futures need ExecutionContext to execute
callback and operations
If we have ActorSystem in implicit scope
Future will use default dispatcher as
ExecutionContext
8. Promise
The other side of Future is a Promise.
Think that the entity that creates a Future is a
Requester and the one that can respond back has
a Promise.
We hardly use Promise in our code, but it
completes the understanding nonetheless!!
9. Promise Example
object PromiseApp extends App {
implicit val system = ActorSystem("future")
// create a promise
val promise = Promise[String]()
// get an associated future from that promise
val future = promise.future
// successfully fulfill that promise
promise.success("promises are to be kept")
// Extract the value from the Future
println(future.value)
}
10. Composing Futures
Futures are Monadic
There are map and flatMap methods on them
We can therefore compose them monadically
and do asynchronous composition!!
11. Composing Example
import akka.actor.ActorSystem
import akka.dispatch.Future
object CreatingFutureFromAFutureApp extends App {
implicit val system = ActorSystem("future")
// Future[String]
val future = Future { "Hello " + " World" }
// Futures are monadic so we can transform from Future[String] to
Future[Int]
val anotherFuture = future map {
aString => aString.length
}
}
12. Sync Wait On Future
There is an Await method if we have to wait
for a Future to complete.
Always avoid this. Use it as last option.
Never block thats the whole point.
13. Sync Wait Example
object SyncWaitOnFuture extends App {
implicit val system = ActorSystem("future")
implicit val timeout = Timeout(50000 milliseconds)
val future = Future { "Hello " + " World" }
val anotherFuture = future map {
aString => aString.length
}
// try to avoid this as much as possible
val number = Await.result(anotherFuture,
timeout.duration)
println("String length is " + number)
}
14. Async Wait
Future has several callbacks. They are
onComplete: It will either be a Success or a
Failure
onSuccess: It will be invoked only when Future
is successful
onFailure: It will be invoked only when Future
got a Throwable in it.
15. Async Wait Example
import akka.actor.ActorSystem
import akka.dispatch.Future
object AsyncWaitOnFuture extends App {
implicit val system = ActorSystem("future")
val future = Future { "Hello " + " World" }
val anotherFuture = future map {
aString => aString.length
}
anotherFuture onSuccess {
case number => println("String length is " + number)
}
}
16. Using Futures
Futures allows us to do a data flow style of
programming
We know, there can be a certain type of value in
a Future. So, we can do asynchronous composition
on that Future.
This will result (yield) a new Future. We do not
block as we compose even when we do not have a
value yet
17. Futures Example
We have an identity function that sleeps for 3
seconds
We want make a call to it three times gather their
result and sum them
Normal code as expected will take nine seconds :(
With Futures we can do it in three seconds :)
18. Futures Example...
Here is the code for identity function. Followed by
creation of three futures.
// creating three futures
val future1 = Future { identity(1) }
val future2 = Future { identity(2) }
val future3 = Future { identity(3) }
def identity(number: Int): Int = {
Thread.sleep(3000)
number
}
19. Futures Example...
Now composing code using flatMap and Map
// composing using map and flatMqp
// not concise at all :(
val oneFinalFuture = future1 flatMap {
result1 =>
future2 flatMap {
result2 =>
future3 map {
result3 => result1 + result2 + result3
}
}
}
20. Futures Example...
Now composing code using for expressions
// for expressions are just a sugar. They are really
concise :)
val finalFuture = for {
result1 <- future1
result2 <- future2
result3 <- future3
} yield result1 + result2 + result3
21. Futures Example...
Now we issue a callback to collect result
finalFuture onSuccess {
case sum =>
println("sum is " + sum)
}