Scala Spray.io-将处理委托给其他参与者
我使用Spray.io框架实现了一个REST服务。此类服务必须接收一些“搜索”查询,处理它们并将结果发送回客户端。执行搜索的代码位于单独的actor-SearchActor中,因此在收到用户的(JSON)查询后,我将(使用ask模式)此查询重新发送给我的SearchActor。但我真正不明白的是,我必须如何实现spray.io route actor和我的SearchActor之间的交互 我在这里看到了几个变体,但哪一个更正确,为什么Scala Spray.io-将处理委托给其他参与者,scala,akka,spray,Scala,Akka,Spray,我使用Spray.io框架实现了一个REST服务。此类服务必须接收一些“搜索”查询,处理它们并将结果发送回客户端。执行搜索的代码位于单独的actor-SearchActor中,因此在收到用户的(JSON)查询后,我将(使用ask模式)此查询重新发送给我的SearchActor。但我真正不明白的是,我必须如何实现spray.io route actor和我的SearchActor之间的交互 我在这里看到了几个变体,但哪一个更正确,为什么 在启动时创建一个SearchActor实例,并将每个请求发送
您不必使用ask模式。事实上,它将为您的每个请求创建一个线程,而这可能不是您想要的。我建议您使用
告诉
。为此,您可以为每个请求生成一个新的Actor
(比线程便宜),它的一个构造函数字段中有RequestContext
。您将使用此上下文返回响应,通常使用其complete
方法
示例代码
class RESTActor extends HttpService {
val route = path("mypath") ~ post {
entity(as[SearchActor.Search]) { search => ctx =>
SearchActor(ctx) ! search
}
}
}
case class SearchActor(ctx: RequestContext) {
def receive = {
case msg: Search => //... search process
case msg: Result => ctx.complete(msg) // sends back reply
}
}
变量#1在初始实现后是不可能的-您可能希望扩展,因此单个阻塞参与者是不好的
变体#2和#3并没有太大区别——创建新的参与者成本低廉,开销最小。由于您的演员可能会经常死亡(即后端不可用),我想说#2是一条路要走
具体的实现思想见Akka doc=>ask的一些说明:创建一个临时的一次性参与者,用于接收对消息的回复,并使用它完成scala.concurrent.Future;回报说未来。Spray在其指令中处理未来。所以,不,它不会创建线程。上述方法与使用ask模式非常相似。这取决于您想在何处编写业务逻辑。关于告诉/询问差异的有趣讨论=>