user4114581
user4114581

Reputation:

AsyncContext infinite thread termination

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

Answers (1)

Andy Guibert
Andy Guibert

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:

  • Setting a timeout for the request via AsyncContext.setTimeout(long)
  • Overriding the Servlet 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).
  • Storing a reference to the thread manually in the servlet class and stopping it in the Servlet 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

Related Questions