首页 文章

喷洒死信

提问于
浏览
2

我正在尝试执行以下代码

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 回答

  • 0

    sender 实际上是一个函数,所以你可以编写 sender() 来表明它不只是访问一个不可变的值 . 当你在future.onComplete中调用 sender 时, sender 的值不再有效 .

    我之前遇到过这个问题,我解决的方法是在未来之外保存发件人的 Value :

    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")
      }
    }
    
  • 4

    好吧,刚解决它试图阻止我的未来 .

    我刚刚创建了一个阻止版本

    OfferService.genericService.getByIdBlocking(id)
    

    在哪里我用它封锁了

    Await.result
    

    然后它奏效了!

    所以基本上我不得不让akka在未来使用ask模式来接受我的调用,但是在actor中进行阻塞操作 .

相关问题