2

I am creating a sample with Akka Remote Actor with RemoteLookupProxyForwarder as define in Akka In Action book. My requirements are like create an actor remotely but using code configuration. RemoteLookupProxyForwarder is work like to lookup remote actor system, if actor system is available create an remote actor otherwise wait.

With he help for application.conf, this had done successfully and working fine as aspected behavior.

But using code the issue is, If remote actor is not available the proxy actor not able to look up actor and when messages are send to remote actor, all messages are going to deadletters.

Remote Proxy Actor Code:

class RemoteLookupProxyForwarder extends Actor with ActorLogging {

  context.setReceiveTimeout(3 seconds)
  deployAndWatch

  def deployAndWatch: Unit = {
    val actor = context.actorOf(Props[RemoteActorR1], "echo")
    context.watch(actor)
    log.info("switching to may be active state")
    context.become(maybeActive(actor))
    context.setReceiveTimeout(Duration.Undefined)
  }


  def deploying: Receive = {
    case ReceiveTimeout =>
      deployAndWatch

    case msg => log.error(s"Ignoring message $msg, remote actor is not ready yet")
  }

  def maybeActive(actor: ActorRef): Receive = {
    case Terminated(actor) =>
      log.info(s"Actor $actor terminated.")
      log.info("switching to deploying state")
      context.become(deploying)
      context.setReceiveTimeout(3 seconds)
      deployAndWatch

    case msg => actor forward msg
  }

  override def receive = deploying
}

object RemoteLookupProxyForwarder {
  def props = Props(new RemoteLookupProxyForwarder)

  def name = "forwarder"
}

Remote 1 actor system:

class RemoteActorR1 extends Actor with ActorLogging {

  override def receive: Receive = {
    case msg => log.info(s"Server Received $msg")
  }
}

object RemoteActorR1 {

  def main(args: Array[String]): Unit = {
    val config = ConfigFactory.parseString(conf)
    ActorSystem("remote-r1", config)
  }

  val conf =
    """
      |akka {
      |  log-dead-letters = "OFF"
      |
      |  actor {
      |    provider = "akka.remote.RemoteActorRefProvider"
      |  }
      |
      |  remote {
      |    enabled-transports = ["akka.remote.netty.tcp"]
      |    netty.tcp {
      |      hostname = "0.0.0.0"
      |      port = 2551
      |    }
      |  }
      |}
    """.stripMargin
}

Remote 2 actor system:

object RemoteActorR3 extends App {

  val uri = "akka.tcp://remote-r1@0.0.0.0:2551"
  val remoteR1Address = AddressFromURIString(uri)

  val props = Props[RemoteLookupProxyForwarder].withDeploy(
    Deploy(scope = RemoteScope(remoteR1Address))
  )

  val conf =
    """
      |akka {
      |  log-dead-letters = "OFF"
      |
      |  actor {
      |    provider = "akka.remote.RemoteActorRefProvider"
      |  }
      |
      |  remote {
      |    enabled-transports = ["akka.remote.netty.tcp"]
      |    netty.tcp {
      |      hostname = "0.0.0.0"
      |      port = 2553
      |    }
      |  }
      |}
    """.stripMargin

  val config = ConfigFactory.parseString(conf)
  val ref = ActorSystem("remote-r3", config)
  val remoteR1 = ref.actorOf(props, RemoteLookupProxyForwarder.name)

  Thread.sleep(30000)
  println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")
  remoteR1 ! "Hello Dude1"
  remoteR1 ! "Hello Dude2"
  remoteR1 ! "Hello Dude3"
}

Using application.conf config this example run fine because in config, we describe two deployments, but is the case of code, still not able to find how to define muliple deployement.

application.conf config with mupltiple deployement:

val conf =
    """
      |akka {
      |  log-dead-letters = "OFF"
      |
      |  actor {
      |    provider = "akka.remote.RemoteActorRefProvider"
      |
      |    deployment {
      |     /echo {
      |       remote = "akka.tcp://remote-r1@0.0.0.0:2551"
      |      }
      |
      |     /forwarder/echo {
      |       remote = "akka.tcp://remote-r1@0.0.0.0:2551"
      |      }
      |    }
      |  }
      |
      |  remote {
      |    enabled-transports = ["akka.remote.netty.tcp"]
      |    netty.tcp {
      |      hostname = "0.0.0.0"
      |      port = 2552
      |    }
      |  }
      |}
    """.stripMargin

My assumptions are, in the code, I am defining only one deployment, that's way sample does not work as expectedly. So, how can we define multiple deployments ?

Harmeet Singh Taara
  • 6,483
  • 20
  • 73
  • 126

0 Answers0