2012-09-17 50 views
6

我正在與Akka 2製作一個小型緩存演員,並且讓演員不會阻止我在期貨內執行所有計算。然而,一個問題是,這個角色還需要與不在actor中的代碼進行交互,這樣我需要使用「ask」模式來獲得一個值。Akka在迴應非演員代碼時避免包裝未來

我的問題是,如何在使用ask模式時避免將未來的計算包裹在另一個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功能,但恐怕這並不被計數爲「響應」非演員代碼

回答

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

+0

奇怪的是,這正是我的原始僞代碼,甚至沒有測試它,因爲我認爲pipeTo不會作爲「響應」工作。這就是我沒有測試,只是假設!雖然事實被告知這種行爲不在我上面提到的文檔中。非常感謝Viktor! – Aktau

+3

相信巴生 –

+0

我想知道「pipeTo發件人」如何安全地訪問發件人。我明白爲什麼你不能在Future中訪問發件人,但是pipeTo發件人怎麼沒有同樣的問題。是否因爲pipeTo在未來完成之前在演員的上下文中評估發件人? –

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

+0

但是,這不會發送兩次嗎?一旦未來[未來[...]](發送者!未來{...})和另一次未來[...]( sender!value)?它是否適用於非演員調用代碼?如何使用CalcResult消息? – Aktau

+2

已更新代碼。實際上,此解決方案來自文章(http://letitcrash.com/post/30509298968/case -study-an-auto-updating-cache-using-actors),我沒時間去看現在就哄它。希望這對你有幫助。 –

+0

呵呵,謝謝!幾個小時前我正在讀這個源文件,其實是因爲它談到了Akka和緩存。我想我沒有把它徹底讀完,似乎在經過仔細檢查之後,或多或少地按照我想要的方式來做。如果它按預期工作,我會選擇你的答案作爲正確的答案。 – Aktau