Spray Dead Letter msg

时间:2015-06-09 18:36:04

标签: scala akka actor spray

我正在尝试执行以下代码

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())

我相信未来。演员内部的完成导致出错。

有什么想法吗?

2 个答案:

答案 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中进行阻塞操作。