【问题标题】:Akka actoreRef with macWire DI, actoreRef is not set带有macWire DI的Akka actoreRef,未设置actoreRef
【发布时间】:2018-08-03 03:20:00
【问题描述】:

我有 2 个演员,Actor1Actor2Actor1 想将MyMsg1 发送给Actor2,而Actor2 在完成一些工作后得到Future[MyMsg2] 想将MyMsg2 发送给Actor1。我有这种方法,但 DI 失败了。

  1. 场景 1 - 工作场景

    • Actor1 -->MyMsg1-->Actor2
    • Actor2 MyMsgHandler - 处理消息(使用 Future),使用MyMsg2 将 pipeTo 发送到发送者。工作正常,Actor1 接收 MyMsg2
  2. 场景 2 - 失败场景

    • Actor1 有一个通过 MacWire 注入的 bean - myBean
    • myBeanActor2 作为 bean 注入,并将 MyMsg1 发送到 Actor2
    • Actor2 MyMsgHandler 处理消息(使用 Future),对发送者执行 pipeTo 并尝试发送 MyMsg2 - 转到 deadLetter。发送者的演员 Ref 永远不会被设置。

我该如何解决这个问题?

也粘贴代码

class Actor1(failedService: FailedService, actor2: ActorRef @@ Actor2) extends Actor{
  override def receive: Receive = {
    case TriggerActor1() =>
      println("Actor1 triggered from REST controller. Send msg to actor 2")
      failedService.testSend()
      //actor2 ! Msg1()
    case Msg2() => println("got msg2 from actor 1")
  }

class Actor2 extends Actor {
  override def receive: Receive = {
    case Msg1() => {
      println("send without future")
      val origsender = sender()
      origsender ! Msg2()
    }
  }

class FailedService(actor2: ActorRef@@Actor2) {
  def testSend() = {
    actor2 ! Msg1()
  }
}

使用我上面共享的当前代码,Actor1 能够将Msg1 发送到Actor2 actor2 回复 Msg2Msg2 进入死信。我收到以下错误 akka.actor.DeadLetterActorRef - Message [backup.failedakka.Msg2] from Actor[akka://application/user/actor2#-662746578] to Actor[akka://application/deadLetters] was not delivered. [1] dead letters encountered.

但是,如果在我的 Actor1 中使用 failedService.testSend() 行,我取消注释它下面的行 并用它来交流,一切正常。 Q现在清楚了吗?我正在使用 MacWire 注入依赖项

【问题讨论】:

  • 您可以添加您的代码吗?我想帮忙。
  • @HuntsMan,我也贴了代码
  • 您好,我认为是因为您使用 FailedService 作为网关而不是参与者,并且当参与者 2 将 Msg2 发送给发送者时,发送者是 FailedService 并且当前已终止并且已经死亡。和。你可以直接联系 Actor1 到 Actor2 顺便说一句 FailedService 不是演员。

标签: scala playframework akka akka-http macwire


【解决方案1】:

! 定义为:

def !(message: Any)(implicit sender: ActorRef = Actor.noSender): Unit

您现在可以看到问题了,FailedService 范围内没有隐式发送者,尽管它在参与者实现“内部”的范围内。

我想你想做:

class FailedService(actor2: ActorRef@@Actor2) {
  def testSend(implicit sender: ActorRef) = {
    actor2 ! Msg1()
  }
}

【讨论】:

  • 谢谢。看起来它有效。我将进行更多测试并标记答案。你能帮我多了解一下发件人是如何通过的吗?我知道使用隐式,让我们说如果我说implicit val a = 10,这是一个可用的默认 int,或者我可以提供隐式序列化程序等。但我对柯里化以及隐式如何帮助这里传递 ref 有点困惑。还有什么解释吗?
  • 对不起,这个地方太小了,无法详细解释……让我链接一个documentation page,应该会有所帮助。
  • 基本上在actor类中你有一个隐式的ActorRef定义(由一个基类),它被传递给!“隐式”:)。在 testSend 方法中,您没有隐含的范围;一个隐式参数实际上声明了两件事:一个传入参数应该在调用站点范围内由 scalac 搜索,并且在函数内部该值被视为隐式值(因此 scalac 会找到它并自动将其传递给函数)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-11
  • 2013-05-17
  • 1970-01-01
  • 1970-01-01
  • 2016-05-26
  • 1970-01-01
相关资源
最近更新 更多