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?
我在后台有一个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?