Reputation:
I'm a bit confused how servlet container terminates AsyncContext in application undeployment phase or simply timeout. For example application developer has following code snippet:
@WebServlet(name = "MyServlet", urlPatterns = "/myServlet", asyncSupported = true)
public class MyServlet extends HttpServlet {
private static Logger log = Logger.getLogger(MyServlet.class);
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
AsyncContext asyncContext = request.startAsync();
asyncContext.start(new Runnable() {
@Override
public void run() {
log.debug("Start of Task");
try {
while(true) {
response.getWriter().println("random text");
Thread.sleep(100);
}
}catch(Exception e) {
log.warn("Async processing exception: " + e.getMessage);
}
asyncContext.complete();
log.debug("End of Task");
}
});
}
}
Here is AsyncContext starts runnable that never ends or until some exception will be thrown in a while loop. So the question is how container will terminate the thread that is running such infinite runnable. The only idea that comes in mind is thread.stop();
but it's deprecated. I almost sure that container doesn't invoke thread.interrupt();
because it doesn't guarantee thread interruption referencing to javadoc and here developer set up condition while-true instead of while-not-interrupted thus not responsible for such case.
Any suggestions appreciated.
Upvotes: 2
Views: 561
Reputation: 42926
The web container can't do anything to force shutdown a thread if the the application developer has intentionally made it loop infinitely.
Fortunately, there are several mechanisms available to an application programmer to ensure that an AsyncContext
doesn't run infinitely. Some ideas of the top of my head are:
AsyncContext.setTimeout(long)
destory()
method and calling AsyncContext.complte()
which will invoke AsyncListener.onComplete(AsyncEvent)
on each listener. You could then attach a listener that stops the process, after adding the listener using AsyncContext.addListener(AsyncListener)
.destory()
method.The main idea is that if you are going to write a Thread that will loop indefinitely (and you care about quiescing threads on shutdown) you are going to need to write some code to ensure your Thread gets stopped properly.
There is a chance that the thread used by AsyncContext.start(Runnable)
is from a managed thread pool:
AsyncContext.start(Runnable)
: Causes the container to dispatch a thread, possibly from a managed thread pool, to run the specified Runnable.
However, since the spec is not firm on this you would need to manually investigate how your Java EE implementation interpreted this bit to see if it uses a managed thread or not. If it does, your thread may be stopped automatically for you when the app server stops.
Upvotes: 1