Using future callback inside akka actor

akka, callback, concurrency, future, scala

Solution

It means this:

class NotThreadSafeActor extends Actor {

  import context.dispatcher

  var counter = 0

  def receive = {
    case any =>
      counter = counter + 1
      Future {
        // do something else on a future
        Thread.sleep(2000)
      }.onComplete {
        _ => counter = counter + 1
      }
  }
}

In this example, both the actor's receive method, and the Future's onComplete change the mutable variable `counter`. In this toy example its easier to see, but the Future call might be nested methods that equally capture a mutable variable.

The issue is that the `onComplete` call might execute on a different thread to the actor itself, so its perfectly possible to have one thread executing `receive` and another executing `onComplete` thus giving you a race condition. Which negates the point of an actor in the first place.

Problem

I've found in Akka docs: When using future callbacks, such as onComplete, onSuccess, and onFailure, inside actors you need to carefully avoid closing over the containing actor’s reference, i.e. do not call methods or access mutable state on the enclosing actor from within the callback. So does it mean that i should always use `future pipeTo self` and then call some functions? Or i can still use callbacks with method, then how should i avoid concurrency bugs?

Original source