Подключение Akka PoisonPill к актерской системе и крюкам отключения JVM - PullRequest
0 голосов
/ 02 ноября 2018

Akka / Java здесь, хотя у меня есть базовое понимание Scala. Новое в Акке. У меня есть класс Master, который запускается при срабатывании системы акторов, которая управляет тремя детьми: Fizz, Buzz и Foo.

Когда Master запускается, этот вызов doSomething() может выдать NoSuchElementException. Если это произойдет, я бы хотел, чтобы 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 для обработки брошенного NoSuchElementException для меня, поэтому я должен поставить здесь трик-поймать, чтобы справиться с этим
  • Мое понимание из PoisonPill заключается в том, что он отключает детей принимающего актера, а затем отключает актера
  • Тем не менее, я все еще сомневаюсь, отключит ли PoisonPill систему акторов , если , то актер оказывается актером root / верхнего уровня, и я также не вижу, как я могу подключите PoisonPill, чтобы не только отключить систему актера, но и задействовать крюк отключения JVM

Когда я запускаю этот код, я не вижу никаких свидетельств выключения системы актера, она просто зависает. Любые идеи, как я могу соединить все это вместе, чтобы достичь желаемого эффекта?

Ответы [ 2 ]

0 голосов
/ 07 ноября 2018

Вы можете изменить стратегию надзора для опекуна пользователя:

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

Если у вас есть опекун пользователя, который эскалирует какие-либо исключения, а затем выдает исключение NoSuchElementException, в результате это исключение окажется у корневого опекуна, в результате чего ваша система завершит работу.

0 голосов
/ 02 ноября 2018

Одним из способов достижения желаемого поведения является вызов главного актера 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();
}

Скоординированное отключение доступно для процедур отключения, которые более сложны.

...