Search code examples
scalaakkaakka-remote-actorakka-remoting

Creating Remote Actors Programmatically is not working


I am creating remote akka actor programmatically.

Below is the Program -

package remoting.programatic.demo

import akka.actor.{ActorSystem, Props}
import com.typesafe.config.ConfigFactory
import remoting.config.demo.RemoteActor

object RemoteActorApp extends App {

  val system = ActorSystem("RemoteNodeApp", ConfigFactory.load().getConfig("RemoteProgrammatically"))
  val remoteActor = system.actorOf(Props[RemoteActor], name = "remoteActorAddr")

  remoteActor ! "Hello!"

  val actorSelection = system.actorSelection("akka.tcp://RemoteNodeApp@localhost:2553/user/remoteActorAddr")
  Thread.sleep(4000L)

  actorSelection ! "Hello!"

}

The configuration is -

RemoteProgrammatically {
  akka {
    actor {
      provider = "akka.remote.RemoteActorRefProvider"
      deployment {
        /remoteActorAddr {
          remote = "akka.tcp://RemoteNodeApp@localhost:2553"
        }
      }
    }
    remote {
      enabled-transports = ["akka.remote.netty.tcp"]
      netty.tcp {
        hostname = "localhost"
        port = 2553
      }
    }
  }
}

The output after running the program is -

[INFO] [12/27/2017 10:37:30.053] [main] [akka.remote.Remoting] Starting remoting
[INFO] [12/27/2017 10:37:30.378] [main] [akka.remote.Remoting] Remoting started; listening on addresses :[akka.tcp://RemoteNodeApp@localhost:2553]
[INFO] [12/27/2017 10:37:30.379] [main] [akka.remote.Remoting] Remoting now listens on addresses: [akka.tcp://RemoteNodeApp@localhost:2553]
[INFO] [12/27/2017 10:37:30.418] [RemoteNodeApp-akka.actor.default-dispatcher-14] [akka://RemoteNodeApp/deadLetters] Message [java.lang.String] from Actor[akka://RemoteNodeApp/user/remoteActorAddr#-766312407] to Actor[akka://RemoteNodeApp/deadLetters] was not delivered. [1] dead letters encountered. This logging can be turned off or adjusted with configuration settings 'akka.log-dead-letters' and 'akka.log-dead-letters-during-shutdown'.
[INFO] [12/27/2017 10:37:34.419] [RemoteNodeApp-akka.actor.default-dispatcher-14] [akka://RemoteNodeApp/deadLetters] Message [java.lang.String] from Actor[akka://RemoteNodeApp/user/remoteActorAddr#-766312407] to Actor[akka://RemoteNodeApp/deadLetters] was not delivered. [2] dead letters encountered. This logging can be turned off or adjusted with configuration settings 'akka.log-dead-letters' and 'akka.log-dead-letters-during-shutdown'.

The message I sent to actor is always going into the dead letters. Looks like remoteActorAddr is not created successfully at RemoteNodeApp actor system. Any Idea why the actor is not created and why the message always goes into dead letters. Thanks.


Solution

  • Message [java.lang.String] from Actor[akka://RemoteNodeApp/user/remoteActorAddr#-766312407] to Actor[akka://RemoteNodeApp/deadLetters] was not delivered. [1] dead letters encountered.
    

    The above excerpt from your logs is saying the dead letters mailbox is encountered when sending a string message from the remote actor. The remote actor is apparently sending a message to sender(), which is dead letters in this case because the messages that the remote actor received were sent with tell (!) from outside an actor. In other words, the remote actor is created successfully, but the following two messages are sent from a non-actor, which causes sender() in the remote actor to resolve to dead letters:

    remoteActor ! "Hello!"
    ...
    actorSelection ! "Hello!"
    

    From the documentation (emphasis mine):

    actorRef ! message
    

    If invoked from within an Actor, then the sending actor reference will be implicitly passed along with the message and available to the receiving Actor in its sender(): ActorRef member method. The target actor can use this to reply to the original sender, by using sender() ! replyMsg.

    If invoked from an instance that is not an Actor the sender will be deadLetters actor reference by default.

    Send the messages from another actor, or use the ask pattern (which creates an internal actor to handle the reply).