I'm making a small caching actor with Akka 2 and to make the actor not block I perform all calculations inside futures. However a problem is that this actor also need to interact with with code that is not itself in an actor, so that I need to use the "ask" pattern to get a value.
My question is, how do I avoid wrapping the Future of my calculation inside another Future when using the ask pattern?
For example
val f = myCache ? GetOrCalc("myKey", myCalculation) // this will be a Future[Future[...]] but I would like a Future[...]
// meanwhile, inside the actor
def receive = {
case GetOrCalc(key, calculation) =>
if (keyNotExists) sender ! Future { calculation() } // calculation() is long-running
else sender ! cacheMap(key)
}
Ideally I could use the Future.pipeTo function but I'm afraid this doesn't get counted as a "response" for non-actor code
This is the solution:
val f = myCache ? GetOrCalc("myKey", myCalculation)
def receive = {
case GetOrCalc(key, calculation) =>
if (keyNotExists) Future { calculation() } pipeTo sender
else sender ! cacheMap(key)
}
Send-And-Receive-Future">http://doc.akka.io/docs/akka/2.0.3/scala/actors.html#Ask_Send-And-Receive-Future
Add onComplete to the calculation future.
def receive = {
case GetOrCalc(key, calculation) =>
if (keyNotExists) // calculation() is long-running
Future { calculation() } onComplete {
case Right(result) => result match {
case Some(value) => sender ! value
case None => sender ! Status.Failure(new Exception("Cannot find the value"))
}
case Left(ex) =>
sender ! Status.Failure(ex)
}
else sender ! cacheMap(key)
}
And there is an article about using Akka to build a cache system. http://letitcrash.com/post/30509298968/case-study-an-auto-updating-cache-using-actors
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With