2014-10-11 50 views
5

使用Play後!框架有一段時間,我正在第一次看Spray。我從我在GitHub上找到的一個示例開始,現在我想修改它,但要獲得它的工作方式並不容易。在噴霧路線中調用演員並等待演員的響應

如何在下面的代碼中等待來自演員的消息?

package api 

import akka.actor.ActorRef 
import scala.concurrent.ExecutionContext 
import spray.routing.Directives 
import core.ClassifierActor 

class ClassifierService(classifier: ActorRef)(implicit executionContext: ExecutionContext) 
    extends Directives with DefaultJsonFormats { 

    import ClassifierActor._ 

    implicit val classifyMessageFormat = jsonFormat4(ClassifyMessage) 

    val route = 
    path("classify") { 
     post { 
     handleWith { 
      // The ClassifierActor gets a ClassifyMessage and 
      // sends a ClassifiedMessage back to the sender. 
      // How can wait for the ClassifiedMessage here 
      // and send a HttpResponse back? 
      cm: ClassifyMessage => classifier ! cm 
      // ??? 
     } 
     } 
    } 

} 
+0

我沒有編寫我們的路由代碼,所以我不知道最好的方法,但廣泛地說,你永遠不會等待:而是將請求交給一個演員,或者通過一個告訴負責一旦處理完成就發送回覆。 – Rup 2014-10-11 11:12:28

+0

我是Spray的新手,所以我無法從您的回覆中獲得任何優勢。我寧願需要一段代碼。 – Max 2014-10-11 13:28:32

回答

12

噴霧已經基於akka.io

因此,如果你想只是爲了完成與演員響應你的路線,你可以用問格局

import akka.pattern.ask 
import scala.concurrent.duration._ 
implicit val timeout = Timeout(5 seconds) // needed for `?` below 

val route = 
    path("classify") { 
     post { 
     onComplete(actorResponse(yourActor, yourMessage)) { 
      complete(_) 
     } 
     } 
    } 

def actorResponse[T](actor: ActorRef, msg: ClassifyMessage): Future[T] = 
(actor ? msg).mapTo[T] 

如果你要轉發請求您的演員模型和完整的演員系統中的某個地方的路線,您需要將RequestContext轉發給演員。也許,這example可以幫助你。祝你好運!

+0

謝謝!您可能會添加'import scala.concurrent.Future',因爲Java也有未來。而'import akka.actor.Actor'也是因爲它也是必需的。 – akauppi 2015-03-10 10:53:52

+0

一個重要的注意事項:該人已經在使用演員(請參閱q中的「分類器:ActorRef」)。如果僅僅是尋找一種多線程響應邏輯的方式,Future [HttpResponse]就是要走的路,而不是演員。請參閱https://www.chrisstucchio.com/blog/2013/actors_vs_futures.html – akauppi 2015-03-12 08:42:49

3

看看我的示例項目。 This service使用期貨來完成路線。就像Rup評論的那樣,等待迴應是不好的做法。立即返回未來,並在獲得結果時完成。

在您的示例中classifier ! cm正在使用actor「tell」模式。它向classifier演員發送消息cm並繼續前進。如果您希望在未來使用「詢問」模式:classifier ? cm。在你的cm演員的接收方法中,你將會返回一個將來會返回的未來sender ! responseMsg