Playframework 2.3 因 Akka 作业的代码更改而关闭 运行

Playframework 2.3 shutdown on code changes with an Akka job running

我在后台有一个akka任务运行来监听UDP包。但是,当我这样做并更改代码时,系统会重新编译,但是 stalls/hangs 然后我需要完全停止并重新启动(如果每次更改后都需要这样做,这会花费很多时间) .当我不开始 Hakka 任务时,它工作正常。这是控制台输出:

[info] play - database [default] connected at jdbc:h2:mem:play
[info] play - Starting application default Akka system.
[info] application - Starting UDP server
[info] play - Application started (Dev)
[debug] application - Ready to receive broadcast packets!
[info] Compiling 1 Scala source and 1 Java source to /Users/Luuk/Documents/Java/temperature-control/target/scala-2.11/classes...
[info] Compiling 1 Scala source and 1 Java source to /Users/Luuk/Documents/Java/temperature-control/target/scala-2.11/classes...
[success] Compiled in 6s
[info] Compiling 1 Scala source to /Users/Luuk/Documents/Java/temperature-control/target/scala-2.11/classes...

--- (RELOAD) ---

[info] play - Shutdown application default Akka system.

我正在使用 IDEA 14。

这是我的全局: public class 全局扩展 GlobalSettings {

@Override
public void onStart(Application app) {
    if (SensorRole.find.findRowCount() != SensorRole.RoleName.values().length) {
        for (SensorRole.RoleName roleName : SensorRole.RoleName.values()) {
            SensorRole newRole = new SensorRole();
            newRole.name = roleName.toString();
            newRole.save();
        }


    }

    ActorRef instance = Akka.system().actorOf(Props.create(UDPBroadcastServer.class), "UDPServer");
    instance.tell("Start", ActorRef.noSender());

    super.onStart(app);
}

@Override
public void onStop(Application app){
    Logger.debug("Stopping system...");
    Akka.system().shutdown();

    super.onStop(app);
}

}

和 UDPBroadcastServer:

public class UDPBroadcastServer extends UntypedActor {

    DatagramSocket socket;
    boolean stop;

    @Override
    public void postStop() throws Exception {
        super.postStop();
        stop = true;
        Logger.info("Master Killed");
    }

    @Override
    public void onReceive(Object command) throws Exception {
        Logger.info("Starting UDP server");
        stop = false;
    String action = (String) command;
    if (action.equals("Start")) {
        try {
            //Keep a socket open to listen to all the UDP trafic that is destined for this port
            socket = new DatagramSocket(8888, InetAddress.getByName("0.0.0.0"));

            socket.setBroadcast(true);

            while (!stop) {
                Logger.debug("Ready to receive broadcast packets!");

                //Receive a packet
                byte[] recvBuf = new byte[15000];
                packet = new DatagramPacket(recvBuf, recvBuf.length);
                socket.receive(packet);

                //Packet received
                Logger.debug("Discovery packet received from: " + packet.getAddress().getHostAddress());
                Logger.debug("Packet received; data: " + new String(packet.getData()));

                //See if the packet holds the right command (message)
                String message = new String(packet.getData()).trim();
                if (message.equals("DISCOVER_TEMPSERVER_REQUEST")) {
                    byte[] sendData = "DISCOVER_TEMPSERVER_RESPONSE".getBytes();

                    //Send a response
                    DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, packet.getAddress(), packet.getPort());
                    socket.send(sendPacket);

                    Logger.debug("Sent packet to: " + sendPacket.getAddress().getHostAddress());
                }
            }
        } catch (IOException ex) {
            Logger.error("Problem with UDP server:" + ex.getLocalizedMessage());
        }
    } else if (action.equals("Stop")) {
        Logger.debug("Trying to stop process!");
        stop = true;
        if(packet != null) packet = null;
        if(socket.isConnected()) socket.close();
    }
}

[编辑]: 根据表扬,我正在尝试手动停止任务。但是,我无法取回 ActorRef 的句柄。我正在尝试这样做:

    ActorRef test = Akka.system().actorFor("//application/user/UDPServer");
    test.tell("Stop", ActorRef.noSender());
    Logger.debug("Path: " + test.path());
    Akka.system().stop(test);

但是 'Stop' 从未被 Actor 的 'onReceive' 接收到。

我猜你的演员在 socket.receive(packet) 上被屏蔽了。从文档中,您可以理解原因:This method blocks until a datagram is received,因此您的停止标志没有意义。这可能会有所帮助:How to terminate a thread blocking on socket IO operation instantly?