如何从java关闭akka

时间:2016-04-29 03:02:56

标签: java akka

我有一个akka(akka-actor_2.11)应用程序,我们用它来测试我们的一个系统。名为RunCoordinatorActor的顶级actor可以根据工作完成时来自下属的响应来了解。

当工作完成后,RunCoordinatorActor调用getContext().system().shutdown(),然后在main方法中有一个循环检查system.isTerminated()调用返回true。一切正常,我很满意它的工作方式。但是,system.sutdown()system.isTerminated()方法都被标记为已弃用,我试图找出实现正常关闭的正确方法,而不使用它们。

这是我的主要课程:

public static void main(String[] args) throws Exception {
    if (new ArgumentsValidator().validate(args)) {
        // If the arguments are valid then we can load spring application
        // context on here.
        final ApplicationContext context = new AnnotationConfigApplicationContext(
                M6ApplicationContext.class);

        // Use an akka system to be able to send messages in parallel
        // without doing the low level thread manipulation ourselves.
        final ActorSystem system = context.getBean(ActorSystem.class);
        final ActorRef runCoordinator = system.actorOf(SPRING_EXT_PROVIDER.get(system)
                .props("RunCoordinatorActor"), "runCoordinator");
        Thread.sleep(1000);
        runCoordinator.tell(new StartTesting(), ActorRef.noSender());

        do {
            LOGGER.info("Waiting for the process to finish");
            Thread.sleep(60000L);
            // What would be the alternative for isTerminated() code below
        } while (!system.isTerminated());
    }
}

这是我在RunCoordinator类中调用shutdown:

@Named("RunCoordinatorActor")
@Scope("prototype")
public class RunCoordinator extends UntypedActor {
    @Override
    public void onReceive(Object message) throws Exception {
        ....
        if (message instanceof WorkDone) {
            getContext().system().shutdown();
        }
    }
}

我可以看到另一个名为terminate()的方法返回一个Future,如果我用它替换shutdown调用,那么一切正常。

if (message instanceof WorkDone) {
    Future<Terminated> work = getContext().system().terminate();
    // But where should I put the call work.isCompleted()
    // and how would I make the main aware of it
}

我可以在这里shutdown-patterns-in-akka-2找到一些scala示例,但最后他们仍然使用system.shutdown,因此不确定该帖子的最新版本仍然是最新的。

提前感谢您的意见。

1 个答案:

答案 0 :(得分:2)

一旦我仔细观察ActorSystem API,解决方案并不难找到。

我所要做的就是将它添加到我的RunCoordinator类中:

if (message instanceof WorkDone) {
    getContext().system().terminate();
}

在我的主要课程中定义了Future<Terminated> workDone = system.whenTerminated();,在变更之后:

public static void main(String[] args) throws Exception {
    if (new ArgumentsValidator().validate(args)) {
        // If the arguments are valid then we can load spring application
        // context on here.
        final ApplicationContext context = new AnnotationConfigApplicationContext(
                M6ApplicationContext.class);

        // Use an akka system to be able to send messages in parallel
        // without doing the low level thread manipulation ourselves.
        final ActorSystem system = context.getBean(ActorSystem.class);
        final Future<Terminated> workDone = system.whenTerminated();
        final ActorRef runCoordinator = system.actorOf(SPRING_EXT_PROVIDER.get(system)
                .props("RunCoordinatorActor"), "runCoordinator");
        runCoordinator.tell(new StartTesting(), ActorRef.noSender());

        do {
            LOGGER.info("Waiting for the process to finish");
            Thread.sleep(60000L);
        } while (!workDone.isCompleted());
    }
}

此后一切顺利。我仍然感到惊讶谷歌感冒并没有带我去任何显示如何做的现有例子。