1
votes

I am trying to send a request to remote actor using ask pattern. The local actor recieves some value and it performs some task on it and updates it. Then when local actor try to send back the updated value to remote actor , error occurs while sending. How should i handle this error?

Error: [INFO] [03/31/2017 17:28:18.383] [ClientSystem-akka.actor.default-dispatcher-3] [akka://ClientSystem/deadLetters] Message [check.package$Rcvdcxt] from Actor[akka://ClientSystem/user/localA1#1050660737] to Actor[akka://ClientSystem/deadLetters] was not delivered. [1] dead letters encountered.

Remote Actor:

class RemoteActor() extends Actor {

    def receive = { 


    case TaskFromLocal() =>{
        implicit val timeout: Timeout = 15000
        val currentSender = sender
        val f1 = currentSender ? RemoteActor.rtree.cxtA
            f1.onComplete{
            case Success(Rcvdcxt(cxtA))=>
                println("Success"+cxtA)
            case Success(s) =>
                    println("Success :"+s)
            case Failure(ex) =>
                    println("failure:"+ex)
            }
        }


  case _ => println("unknown msg")
  }
}
object RemoteActor{

    def createRndCxtC(count: Int):List[CxtC] = (for (i <- 1 to count) yield CxtC(Random.nextString(5), Random.nextInt())).toList
    def createRndCxtB(count: Int): List[CxtB] = (for (i <- 1 to count) yield CxtB(createRndCxtC(count), Random.nextInt())).toList
    def createRndCxtA(count: Int): List[CxtA] = (for (i <- 1 to count) yield CxtA(createRndCxtC(count), 5)).toList
    var rtree = RCxt(createRndCxtA(1),createRndCxtB(2),1,"")

    def main(args: Array[String]) {     
        val configFile = getClass.getClassLoader.getResource("remote_application.conf").getFile
        val config = ConfigFactory.parseFile(new File(configFile))
        val system = ActorSystem("RemoteSystem" , config)
        val remoteActor = system.actorOf(Props[RemoteActor], name="remote")
        println("remote is ready")
   }   
 }



Local Actor :


class LocalActorA extends Actor{    

  @throws[Exception](classOf[Exception])
  val remoteActor = context.actorSelection("akka.tcp://[email protected]:5150/user/remote")

  def receive = {   



    case TaskLA1(taskA) =>  {

    implicit val timeout: Timeout = 15000
      val rCxt = remoteActor ? TaskFromLocal()   
      val currentSender = sender
      rCxt.onComplete{
            case Success(Rcvdcxt(cxtA))=>
              println("Success"+cxtA)
              println("Sender: "+ sender)
              currentSender ! Rcvdcxt(cxtA)

            case Success(s)=>
              println("Got nothing from Remote"+s)
              currentSender ! "Failuree"

            case Failure(ex) =>
              println("Failure in getting remote")
              currentSender ! "Failure"
            }
    }
  }
}

object LocalActorA {    


    def createRndCxtC(count: Int):List[CxtC] = (for (i <- 1 to count) yield CxtC(Random.nextString(5), Random.nextInt())).toList
    def createRndCxtB(count: Int): List[CxtB] = (for (i <- 1 to count) yield CxtB(createRndCxtC(count), Random.nextInt())).toList
    def createRndCxtA(count: Int): List[CxtA] = (for (i <- 1 to count) yield CxtA(createRndCxtC(count), 3)).toList
    var tree = RCxt(createRndCxtA(2),createRndCxtB(2),1,"")

   def main(args: Array[String]) {
    val configFile = getClass.getClassLoader.getResource("local_application.conf").getFile
    val config = ConfigFactory.parseFile(new File(configFile))
    val system = ActorSystem("ClientSystem",config)
    val localActorA1 = system.actorOf(Props[LocalActorA], name="localA1")
    println("LocalActor A tree : "+tree)
    localActorA1 ! TaskLA1(new DummySum())
   }
}
1

1 Answers

0
votes

Since you didn't post all the code I can't really tell exactly the error, but my best guess is related to the fact that you are calling sender in the onComplete in the LocalActor. This is unsafe and should be avoided at all costs. Instead, do something similar with the remote actor:

class LocalActor {
  def receive = {
    case TaskLA1(taskA) =>
      val currentSender = sender
      rCxt.onComplete {
        case Success(Rcvdcxt(cxtA))=>
          currentSender ! Rcvdcxt(cxtA)
          ...
      }
  }
}