我正在与Akka 2制作一个小型缓存演员并让演员不要阻止我在期货中执行所有计算。然而问题是这个actor还需要与不在actor中的代码进行交互,因此我需要使用“ask”模式来获取值。
我的问题是,在使用ask模式时,如何避免将计算的Future包含在另一个Future中?
例如
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)
}
理想情况下,我可以使用Future.pipeTo函数,但我担心这不会被视为非演员代码的“响应”
答案 0 :(得分:6)
这是解决方案:
val f = myCache ? GetOrCalc("myKey", myCalculation)
def receive = {
case GetOrCalc(key, calculation) =>
if (keyNotExists) Future { calculation() } pipeTo sender
else sender ! cacheMap(key)
}
发送和接收-未来“> HTTP://doc.akka.io/docs/akka/2.0.3/scala/actors.html#Ask_Send-And-Receive-Future
答案 1 :(得分:3)
将onComplete添加到计算未来。
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)
}
还有一篇关于使用Akka构建缓存系统的文章。 http://letitcrash.com/post/30509298968/case-study-an-auto-updating-cache-using-actors