【问题标题】:How to stop an akka thread on shutdown如何在关闭时停止 akka 线程
【发布时间】:2012-06-04 00:27:09
【问题描述】:

我目前正在使用播放框架(2.0.1 版)。 我的应用程序需要收听 udp 广播消息。所以我需要一个新线程来监视套接字并接收所需的字节。 在查看 play 框架后,似乎 Akka 系统用于处理线程/作业。 所以我实现了一个新的后台 akka 任务来读取我的套接字。见下文。一切都按我的预期工作,我能够在后台任务中接收我想要的数据。 我遇到的问题是当我关闭服务器时。在开发中按下 Control D。它显示消息“[info] play - 关闭应用程序默认 Akka 系统。”但随后挂起并且永远不会关闭我的后台线程。

public running = false;
public void onReceive(Object message) {
    if (message instanceof SystemConfiguration) {
        try {
            InetAddress group = InetAddress.getByName("222.1.1.1");
            MulticastSocket socket = new MulticastSocket(54321);
            socket.joinGroup(group);
            running = true;

            while (running) {
                Logger.info("MultiCastController - waiting to receive message");
                byte[] buf = new byte[1000];
                DatagramPacket recv = new DatagramPacket(buf, buf.length);
                socket.setSoTimeout(30000);
                try {
                    socket.receive(recv);
                    String msgString = new String(recv.getData()).trim();
                    Logger.info("retreived: " + msgString);
                } catch (SocketTimeoutException e) {
                    Logger.info("MultiCastController - timed out"
                            + recv.getData().toString());
                }
            }
        } catch (Exception ex) {
            Logger.info("Errror message caught: " + ex.toString());
        }
    } else {
        Logger.info("Error starting multicast receiver incorrect value passed: ");
    }
}

我试图覆盖 post stop,但它似乎从未被调用过。我也试过 akka.system().isTerminated() 但没用。

@Override
public void postStop()
{
    Logger.info("MultiCastController - postStop() - stopping thread");
    running = false;
}

我一直在寻找的另一个可能的选项是有什么方法可以获取 akka 状态吗?它正在关闭,所以我可以做类似的事情

while(运行 && akka.system().alive())。我发现如果我收到一条消息,它会崩溃,因为 ebean 服务器已关闭。我什至可以做一个 hack 并检查它是否还活着?

while(运行 && ebean.server.isalive())

【问题讨论】:

    标签: playframework playframework-2.0 akka


    【解决方案1】:

    将您的线程创建为守护线程,然后在应用程序退出时它会存在。

    或者您可以注册一个回调,以便在 ActorSystem 关闭时执行:

    def registerOnTermination(代码:Runnable):单位

    注册一个代码块(回调)以在此actor系统中的所有actor都已完成后运行 停止了。

    发件人:http://doc.akka.io/api/akka/2.0.1/#akka.actor.ActorSystem

    【讨论】:

      【解决方案2】:

      您可以覆盖 Global.onStop 以向您的演员发送停止消息。如果运行得太晚,您可以在列表的最前面注册一个插件,以便在 Play 开始关闭时立即发送停止消息:

      import play.api.Plugin
      import play.api.Application
      
      class ShutdownObserver(app: Application) extends Plugin {
      
        override def onStop() {
          ... send message to your actor telling it to stop...
        }
      }
      

      然后使用以下命令创建您的 conf/play.plugins 文件:

      1:ShutdownObserver
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-05-29
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多