2014-10-11 49 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