6

我正在用 Akka 2 制作一个小型缓存演员,为了让演员不被阻塞,我在期货中执行所有计算。然而一个问题是这个actor还需要与它本身不在actor中的代码进行交互,所以我需要使用“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 函数,但恐怕这不会被视为非参与者代码的“响应”

4

2 回答 2

6

这是解决方案:

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

于 2012-09-17T15:27:00.087 回答
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

于 2012-09-17T09:21:18.857 回答