4

Lately, during my research about asynchronous processing in Servlets, I came across at at least three ways to implement some functionality using this approach.

The questions are:

  1. Which one is the best?
  2. Maybe some of these approaches are not recommended?
  3. Maybe there is another one approach better than all of mentioned below?

Found approaches:

  1. Using AsyncContext.start(Runnable).

    This approach is quite simple and straightforward. But many serwers executes such a job in thread pool created for HTTP requests (more about it here http://www.nurkiewicz.com/2012/05/javaxservletservletrequeststartasync.html)

  2. Using custom threads pool created during Servlet context initialization

    (sample here: http://www.journaldev.com/2008/async-servlet-feature-of-servlet-3). But can I create my own threads in Servlet container? It was not recommended (or even prohibited) in EJB (before JavaEE7). Can I use JavaSE Executors or should I use ManagedExecutors from JavaEE7 (assuming that I use JavaEE7)?

  3. Using EJB and @Asynchronious annotation

    (example here: https://github.com/wildfly/quickstart/tree/master/servlet-async/src/main/java/org/jboss/as/quickstarts/servlet/async). But here I have no control over threads executing my task (i.e. how many thread should by created etc.)

I would by glad to hear your thoughts on this issue and your experience with AsyncContext.

1 Answer 1

2

All will have the same performance, at the backend all threads are replacing the request processing thread to another thread, so that more requests can be served.

Below you'll find a simple implementation:

@WebServlet(urlPatterns = "/AsyncLongRunningServlet", asyncSupported = true)
public class AsyncLongRunningServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    protected void doGet(HttpServletRequest request,
        HttpServletResponse response) throws ServletException, IOException {
        System.out.println("Request Processing Thread "+Thread.currentThread().getName());

        request.setAttribute("org.apache.catalina.ASYNC_SUPPORTED", true);
        response.setContentType("text/html");
        PrintWriter printWriter=response.getWriter();
        printWriter.println("<html><head><title>Asynchronous servlet</title></head><body>");
        printWriter.println("Request Processing Thread "+Thread.currentThread().getName());
        printWriter.println("<br>");
        printWriter.println("<progress id='progress' max='100')></progress>");
        printWriter.println("<br>");

        AsyncContext asyncCtx = request.startAsync();
        asyncCtx.addListener(new AppAsyncListener());
        asyncCtx.setTimeout(12000);
        //release of request processing thread
        asyncCtx.start(() ->{
            printWriter.println("<br>");
            printWriter.println("Async thread Name "+Thread.currentThread().getName());
            printWriter.println("<br>");

            int i=0;
            while(i<100)
            {
                printWriter.println("<script>document.getElementById('progress').value=\""+i+"\";</script>");
                printWriter.flush();
                try {
                    Thread.sleep(100);
                } catch (Exception e) {
                }
                i++;
            }
            printWriter.println("</body></html>");
            asyncCtx.complete();
        }

    );
        printWriter.println("<br>");
        printWriter.println("End of response");
    }

}



package com.journaldev.servlet.async;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.AsyncEvent;
import javax.servlet.AsyncListener;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebListener;

@WebListener
public class AppAsyncListener implements AsyncListener {

    @Override
    public void onComplete(AsyncEvent asyncEvent) throws IOException {
        System.out.println("AppAsyncListener onComplete");
        // we can do resource cleanup activity here
    }

    @Override
    public void onError(AsyncEvent asyncEvent) throws IOException {
        System.out.println("AppAsyncListener onError");
        //we can return error response to client
    }

    @Override
    public void onStartAsync(AsyncEvent asyncEvent) throws IOException {
        System.out.println("AppAsyncListener onStartAsync");
        //we can log the event here
    }

    @Override
    public void onTimeout(AsyncEvent asyncEvent) throws IOException {
        System.out.println("AppAsyncListener onTimeout");
        //we can send appropriate response to client
        ServletResponse response = asyncEvent.getAsyncContext().getResponse();
        PrintWriter out = response.getWriter();
        out.write("TimeOut Error in Processing");
    }

}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.