How to wait for Akka actor system to terminate?

2020-05-20 08:07发布

I need to start Akka (2.0) actor system, send in some messages, then wait for it to do heavy lifting. After that, I need to do something unrelated to those actors.

I tried to wait for all actors to stop with following code:

val system = new ActorSystem("parallelRunners")
val master = system.actorOf(Props[Master])
master ! Start
system.awaitTermination // <-- hangs here

All actors kill themselves via self ! PoisonPill. What am I doing wrong?

标签: scala akka
7条回答
地球回转人心会变
2楼-- · 2020-05-20 08:08

I found the solution - just call system.shutdown from the master actor:

context.system.shutdown
查看更多
做个烂人
3楼-- · 2020-05-20 08:09

in Akka 2.3.9, it seems that shutting down an actor system and waiting for it to shut down is a two step process:

  1. Initiate the shutdown: actorSystem.shutdown
  2. Wait for its termination in a blocking manner: actorSystem.awaitTermination

As an alternative to step (2), possibly (haven't tested these alternatives) you may alternatively poll on isTerminated or use registerOnTermination for running some code when it's terminated. So it is worth going through the comments of akka.actor.ActorSystem to fathom and choose between these methods for your implementation.

Perhaps I'm missing other options about the API (?) as Future return values could have been nicer.

查看更多
我只想做你的唯一
4楼-- · 2020-05-20 08:20

Just a side note for those running into this question for its title: Apparently, Akka 2.5 does not support actorSystem.awaitTermination anymore. Reason being why might be Akka's philosophy of avoiding any blocking calls. Instead, actorSystem.registerOnTermination(...) can be used as a non-blocking way to do actions while an ActorSystem is being shutdown.

Nonetheless, you can still wait for your actor system to complete via a Future provided by ActorSystem.whenTerminated:

val system = new ActorSystem("parallelRunners")
val master = system.actorOf(Props[Master])
master ! Start

import scala.concurrent.Await
import scala.concurrent.duration._
Await.ready(system.whenTerminated, 365.days)
查看更多
来,给爷笑一个
5楼-- · 2020-05-20 08:26

In Akka 2.4.1 for scala 2.11 it appears to be different again.

system.awaitTermination() is deprecated and the docs instruct us to use Await.result(system.whenTerminated, timeout) instead.

As 203 said, system.terminate is still the way to terminate the system.

Here is some example code I used:

val actorSystem = ActorSystem("ActorSystem")
val myActors = actorSystem.actorOf(Props[MyActor].withRouter(RoundRobinPool(10)), "MyActors")
rainbows.foreach(rainbow => myActors ! rainbow)
Await.ready(actorSystem.whenTerminated, Duration(1, TimeUnit.MINUTES))

Then in the MyActor class I have the line context.system.terminate()

查看更多
狗以群分
6楼-- · 2020-05-20 08:26

As of Akka 2.4, you should use system.awaitTermination() which returns a Future[Terminated] you can wait for.

In order to terminate the system, you should use ActorSystem.terminate (e.g. context.system.terminate() from within an actor when it is finished.

Source: Release Notes

查看更多
冷血范
7楼-- · 2020-05-20 08:31

How about:

import scala.concurrent.Await
import scala.concurrent.duration._

Await.ready(system.terminate(), 5.seconds)

terminate returns a Future:

def terminate(): Future[Terminated]

and you can just await completion of this future.

查看更多
登录 后发表回答