Tuesday, March 25, 2014

How to shutdown 'play' programmaticly based on the corresponding conditions.

      I have got the task to stop 'play'(controller and the whole server) according to some requirements. To be more clear I need to check whether the сurrent request to the given method of the given controller is the last allowed one and then shutdown play.

     The main point that Calling System.exit() is enough to shut down the JVM I have read here: https://groups.google.com/forum/#!searchin/play-framework/system.exit/play-framework/xWAi7tPIEhY/2Ainrixfp8IJ

Cause even  Play.stop(); does not work as expected as per link above from
the 'play-framework' user group.

    But then I faced with the issue on how to return answer with JSON data and only then stopping the 'play' server. ScheduledExecutorService сame to help me). I've read a lot of documentation/articles about built-in play's approaches like async jobs, await and etc, but no one of them can guarantee me then play server will be stopped after returning of JSON answer.

   With ScheduledExecutorService I wait 5 sec after the short json answer and then shut down the 'play' server. Moreover if we assume that the json result will not be back to time of shutdown (which is very very unlikely) then my logic inside deviceConfigurationLocator service kills play server at the next request.

   I've tested this logic with the different scenarios and it works! Play server dies when I want this :-) Below is the my implementation of this task:

package controllers;
@org.springframework.stereotype.Controller
public class DeviceConfig extends RestController {
@Autowired
private IDeviceConfigurationLocator deviceConfigurationLocator;
public Result getDevice(String deviceId) {
Device deviceInfo = deviceConfigurationLocator.getDeviceConfigurationInfo(deviceId);
JsonNode jsonNode = Json.toJson(deviceInfo);
int actualDevicesRequestCount = deviceConfigurationLocator.getActualDevicesRequestCount();
int allowedDevicesRequestCount = deviceConfigurationLocator.getAllowedDevicesRequestCount();
if (actualDevicesRequestCount >= allowedDevicesRequestCount){
ShutdownPlayIfNeeded();
}
return ok(jsonNode);
}
/*
Idea of using "System.exit(-1)" was taken from "Programatically shut down Play 2.0?"
https://groups.google.com/forum/#!searchin/play-framework/system.exit/play-framework/xWAi7tPIEhY/2Ainrixfp8IJ
*/
private void ShutdownPlayIfNeeded() {
final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
final Runnable task = new Runnable() {
public void run() {
System.exit(-1);
}
};
final ScheduledFuture<?> handle =
scheduler.scheduleAtFixedRate(task, 5, 1, TimeUnit.SECONDS);
scheduler.schedule(new Runnable() {
public void run() {
handle.cancel(true);
}
}, 10, TimeUnit.SECONDS);
}
}

P.S. If you have any other ideas on how to stop/shutdown play server in context of my task feel free to tell about this in the comments.

No comments:

Post a Comment