我正在尝试执行以下代码
trait CustomHttpService extends HttpService {
import MyJsonProtocol._
import spray.httpx.SprayJsonSupport._
implicit def executionContext = actorRefFactory.dispatcher
implicit val timeout = Timeout(5 seconds)
val offerActor = actorRefFactory.actorOf(Props[OfferActor], "offer-actor")
val defaultRoute = {
path("offer" / JavaUUID) { uuid =>
get {
respondWithMediaType(`application/json`) {
complete {
(offerActor ? Get(uuid)).mapTo[Offer]
}
}
}
}
}
}
class OfferActor extends Actor {
override def receive = {
case Get(id) =>
val future = OfferService.genericService.getById(id)
future.onComplete {
case Success(s) =>
s match {
case Some(offer) => sender ! offer
case None => println("none")
}
case Failure(f) => f
}
case id: String => println("received string id: " + id)
case _ => println("receive nothing")
}
}
最初我试图直接返回未来,但它给了我一个错误,抱怨我试图投射到我的Offer对象的承诺。
然后我只是丑陋地解决了我在演员中的未来,最终获得了优惠,然后将其返回给发件人。
这样做我得到以下内容:
[06/09/2015 15:16:43.056] [喷雾系统akka.actor.default-调度-4] [akka:// spray-system / deadLetters]消息 来自[com.spray.entity.Offer] 演员[akka://喷雾系统/用户/喷雾演员/提供演员#-617290326]来 演员[akka:// spray-system / deadLetters]未送达。 [2]死了 遇到的字母。可以使用关闭或调整此日志记录 配置设置'akka.log-dead-letters'和 'akka.log止字母-期间关断'。
实际上,我正在发送一个带有我从数据库获得的商品的消息。
相反,如果我只是创建这样的商品,那就完美无缺。
case Get(id) => sender ! Offer(Some(id), "offer", new DateTime())
我相信未来。演员内部的完成导致出错。
有什么想法吗?
答案 0 :(得分:4)
sender
实际上是一个函数,因此您可以编写sender()
来表明它不仅仅是访问不可变值。当你在future.onComplete中调用sender
时,sender
的值将不再有效。
我之前遇到过这个问题,我解决的方法是将发件人的价值保存在未来之外:
class OfferActor extends Actor {
override def receive = {
case Get(id) =>
val future = OfferService.genericService.getById(id)
val replyTo = sender
future.onComplete {
case Success(s) =>
s match {
case Some(offer) => replyTo ! offer
case None => println("none")
}
case Failure(f) => f
}
case id: String => println("received string id: " + id)
case _ => println("receive nothing")
}
}
答案 1 :(得分:0)
嗯,刚刚解决了它试图阻止我的未来。
我刚刚创建了
的阻止版本OfferService.genericService.getByIdBlocking(id)
我用
阻止了它Await.result
然后它奏效了!
所以基本上我不得不让akka在未来使用ask模式来接受我的调用,但是在actor中进行阻塞操作。