我正在尝试执行以下代码
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] [spray-system-akka.actor.default-dispatcher-4] [akka:// spray-system / deadLetters]消息[com.spray.entity.Offer]来自演员[akka:// spray-system / user / spray-actor / offer-actor#-617290326]对演员[akka:// spray-system / deadLetters]未送达 . [2]遇到死信 . 可以使用配置设置'akka.log-dead-letters'和'akka.log-dead-letters-during-shutdown'关闭或调整此日志记录 .
实际上,我正在发送带有我从数据库获得的商品的消息 .
相反,如果我只是创建这样的优惠,那就完美了 .
case Get(id) => sender ! Offer(Some(id), "offer", new DateTime())
我相信未来 . 演员内部的完成导致了一些错误 .
有什么想法吗?
2 回答
sender
实际上是一个函数,所以你可以编写sender()
来表明它不只是访问一个不可变的值 . 当你在future.onComplete中调用sender
时,sender
的值不再有效 .我之前遇到过这个问题,我解决的方法是在未来之外保存发件人的 Value :
好吧,刚解决它试图阻止我的未来 .
我刚刚创建了一个阻止版本
在哪里我用它封锁了
然后它奏效了!
所以基本上我不得不让akka在未来使用ask模式来接受我的调用,但是在actor中进行阻塞操作 .