将Akka PoisonPill连接到actor系统和JVM关闭挂钩

时间:2018-11-02 16:37:24

标签: java java-8 akka

Akka / Java 在这里,尽管我对Scala有基本的了解。 Akka的新手。我有一个{ "baz": "glern", "froboz": "foo again"} 类,它在actor系统启动时启动,该类管理三个孩子:MasterFizzBuzz

启动Foo时,对Master的调用可能引发doSomething()。如果是这样,我希望NoSuchElementException关闭其三个子级,杀死自己,关闭整个actor系统,然后调用自定义系统关闭钩子。迄今为止我最大的尝试:

Master

我的想法是:

  • 由于public class MyApp { public static void main(String[] args) { ActorRef master = actorSystem.actorOf(Props.create(Master.class)); master.tell(new Init(), ActorRef.noSender()); Runtime.getRuntime().addShutdownHook(new Thread() { @Override void run() { System.out.println("Shutting down!"); } }); } } public class Master extends AbstractActor { private Logger log = LoggerFactory.getLogger(this.getClass()); private ActorRef fizz; private ActorRef buzz; private ActorRef foo; public Master() { super(); } @Override public Receive createReceive() { return receiveBuilder() .match(Init.class, init -> { try { fizz = context().actorOf(Props.create(Fizz.class)); buzz = context().actorOf(Props.create(Buzz.class)); foo = context().actorOf(Props.create(Foo.class)); long metric = doSomething(); log.info("After all the children started up \"metric\" was: {}", metric); } catch(NoSuchElementException ex) { self().tell(PoisonPill.getInstance(), self()); } }).build(); } } 是最高角色,因此我无法定义Master来为我处理抛出的SupervisorStrategy,因此我必须在其中放置try-catch处理
  • 我对NoSuchElementException的理解是,它关闭了接收演员的孩子,然后关闭了演员
  • 但是,对于PoisonPill是否关闭actor系统,我仍然感到很困惑。 actor恰好是根/顶级actor,但我也没有看到如何连接PoisonPill不仅可以关闭actor系统,还可以接合JVM的关闭钩子

运行此代码时,我看不到任何有关actor系统关闭的迹象,它只是挂起。有什么想法可以将所有这些联系在一起以实现所需的效果吗?

2 个答案:

答案 0 :(得分:2)

实现所需行为的一种方法是让主actor调用getContext().getSystem().terminate(),并使用ActorSystem.registerOnTermination注册一个包含关机逻辑的回调:

actorSystem.registerOnTermination(new Runnable {
  @Override 
  public void run() {
    System.out.println("Shutting down!");
  }
});

// ...

try {
  // ...
} catch (NoSuchElementException ex) {
  getContext().getSystem().terminate();
}

Coordinated shutdown可用于更复杂的关机过程。

答案 1 :(得分:0)

您可以更改用户监护人的监管策略:

https://doc.akka.io/docs/akka/current/general/supervision.html#user-the-guardian-actor

如果您让用户监护人上报了任何异常,则抛出NoSuchElementException,该异常将最终在根监护人处发生,结果是系统将退出。