Actor and the future: link to a member message on onComplete

During refactoring actor codes written by some other programmers, I came across using a callback Future.onCompleteinside actor A, which is contrary to best practice akka.pattern.pipe. This is a bad idea, because it provides the possibility of race conditions, because the instance Futurecan be executed in another thread.

Looking at the code, we see that onCompleteneither sender, nor any mutable exists in the block var, so it seems pretty safe, at least for this particular case. However, one gray area that interests me is links to urland especially text.

Is it possible that, similar to Closing an Actor's Actor in a Recipient , a race condition occurs so that during a callback call, the onCompletevalue textalready refers to another actor message, causing all the hells to burst?

class B extends akka.actor.Actor {
  def receive = {
    case urlAndText: (String, String) => // do something
  }
}

class A extends akka.actor.Actor {
  case class Insert(url: String)

  def fileUpload(content: String): String = ??? // returns the url of the uploaded content
  val b = context.actorOf(Props(classOf[B]))
  def receive = {
    case text: String =>
      Future {
        fileUpload(text)
      } onComplete {
        case Success(url) =>
          b ! Insert(url, text) // will this be
      }
  }
}
+4
source share
2 answers

Link to textshould be beautiful. The difference is that each β€œinstance” textis a new variable associated with the scope of the current matching block (starting from case text ...). Thus, the created Futureautomatically closes the value text.

sender ( sender() sugared), , Actor, ActorRef , , ( Future onComplete).

, onComplete. :

case text: String =>
  Future {
    fileUpload(text)
  } map { url => 
    Insert(url, text) 
  } pipeTo b

b, .

+4

- , , , .

url text . url - , , . text , , .

, sender var , , , , , , .

+1

Source: https://habr.com/ru/post/1611371/


All Articles