Multithreading – the sender becomes an actor [akka: / / main / deadletters]

I can't figure out why I made a mistake "dead letters"

class MyActor extends Actor {

  private def getIdList = Future { blocking(getIdListSync) }

  private def getIdListSync = {
    val inputStreamRaw = new URL(url).openConnection.getInputStream
    val inputStream = scala.io.source fromInputStream inputStreamRaw
    val json = parse(inputStream getLines() mkString "\n")
    val jsonIds = json \ "ids" \\ classOf[JInt]
    jsonIds take idLimit map (_.toInt)
  }

  def receive = {
    case Get =>

        //doesn't work,the error is "sender" becomes "Actor[akka://Main/deadLetters]"

//      getIdList onComplete {
//        case Success(idList) =>
//          sender ! Result(idList)
//
//        case Failure(e) => // todo
//      }

      //works well
      val idList = getInternalIdListSync
      sender ! Result(idList)

  }
}

As you can see, if future and blocking are used in the method named getidlist, the sender will become actor [akka: / / main / deadletters] Why? Shouldn't I use it?

Solution

The problem is that you invoke the sender in the asynchronous function block. There is a simple rule:

Never close the sender method in a block of code that may execute asynchronously

Sender is a function that returns the sender of the currently processed message The problem is that if you call sender in a callback like onComplete, the callback will be executed asynchronously. This means that during this period, participants can process other messages, so the sender function may not report the sender of the original message

One way to avoid this is to store the sender in a local variable before executing asynchronous code:

def receive = {
  case Get =>
    val s = sender

    // call an asynchronous function
    myAsyncFunction onComplete{ result =>
      s ! result
    }
}

Another method is to use the akka pipeto function as @ vadzim and point out:

import akka.pattern.pipe

def receive = {
  case Get =>
    // call an asynchronous function
    val result = myAsyncFunction

    result pipeTo sender
}

More information about it can be found in the akka documentation: http://doc.akka.io/docs/akka/snapshot/scala/futures.html#Use_With_Actors

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>