Reputation: 1441
I would like to get a future that completes when an Akka actor has handled the PoisonPill.
I have tried:
someRef ? PoisonPill
but this never completes. I think you can only use '!' and not '?'. Any ideas?
Upvotes: 3
Views: 1022
Reputation: 6242
If what you want is to monitor the life-cycle of some child actor, you can simply watch
that actor and handle the Terminated
message accordingly to your logic. For example:
class MyActor extends Actor {
import context._ // to avoid writing context everywhere
val child = actorOf(Props(new ChildActor)) // ChildActor is the type of the actor you are monitoring, the child
watch(child) // subscribe to the Terminated message of the child
override def receive: Receive = {
case "kill" ⇒ child ! PoisonPill // kill the child. You could also use context.stop(child)
case Terminated(`child`) ⇒ println("child died") // handle the termination of the child. Use back-ticks to make child a stable identifier
case _ ⇒ println("meh") // who cares
}
}
Now, if you want an explicit Future
, the first thing that pops in my mind is passing a Promise
to the actor you want to watch, and override postStop
to complete the promise. It would look like this:
class MyActor(p: Promise[Unit]) extends Actor { // receive the Promise to complete
override def receive: Receive = {
case _ ⇒ println("meh") // who cares
}
override def postStop(): Unit = { // after stopped
p.tryComplete(Success(())) // complete the promise
}
}
object Main {
def main(args: Array[String]) {
val system = ActorSystem("test")
val p = Promise[Unit]()
val f = p.future // get the future from the promise
val a = system.actorOf(Props(new MyActor(p))) // send the promise to the actor you want to watch
f onSuccess { // register a callback when the future completes
case _ ⇒ println("actor died")
}
a ! "foo"
a ! PoisonPill
}
}
Hope it helped. Cheers!
Upvotes: 1