0
votes

I have a 2 actors, Actor1 and Actor2. Actor1 wants to send MyMsg1 to Actor2, and Actor2 after doing some work and getting Future[MyMsg2] wants to send MyMsg2 to Actor1. I have got this working one way but it fails with DI.

  1. Scenario 1 - Working scenario

    • Actor1 -->MyMsg1-->Actor2
    • Actor2 MyMsgHandler - Processes message(with Future), does pipeTo to sender with MyMsg2. Works fine, Actor1 recvs MyMsg2
  2. Scenario2 - Failing scenario

    • Actor1 has a bean injected via MacWire - myBean.
    • myBean has Actor2 injected as a bean and sends MyMsg1 to Actor2
    • Actor2 MyMsgHandler processes message(with Future), does pipeTo to sender and tries sending MyMsg2 - Goes to deadLetter. The actor Ref for sender is never set.

How do I fix this?

Pasting code also

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

With my current code as shared above, Actor1 is able to send Msg1 to Actor2 and actor2 responds with Msg2 but Msg2 goes to deadletter. I get the below error 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.

However, if insted of using the line failedService.testSend() in my Actor1, I uncomment the line below it and use that to communicate, things work fine. Is the Q clear now? I am injecting dependencies with MacWire

1
can you add your codes ? ill try to help.HuntsMan
@HuntsMan, I have pasted the code alsocuriousengineer
Hello i think because your using the FailedService as a gateway which is not an actor and when the actor2 send Msg2 to the sender the sender which is FailedService and currently terminated and which is already dead. and. you can contact directly to the Actor1 to Actor2 btw FailedService is not an actor.HuntsMan

1 Answers

1
votes

! is defined as:

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

You can see the problem now, there's no implicit sender in scope of FailedService, although it is in scope "inside" an actor implementation.

I think you want to do:

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