Search code examples
javaservletsjava-ee-6distributed-computingservlet-3.0

Servlet 3.0: How to off-load Async processing to a different JVM?


Servlet 3.0 allows the 'request' thread (or 'main' thread) to delegate long-running processing to some other thread, so as to free itself to receive more requests. Agreed. That is, we are achieving scalability (of requests) by utilizing multi-threading.

But this requires that my 'Servlet container JVM' is capable of such processing. What if I have a multi-tiered architecture where the 'Servlet container JVM' is only the entry point, while the logic for servicing requests lies somewhere else in some other JVM (henceforth called as 'Service JVM' in this post).

What if I want to post the incoming 'request' (or atleast the relevant attributes of the request) to a JMS queue and let the 'request' be grabbed and processed by one out of a pool of 'Service JVMs' ? Wouldnt it be better to delegate the responsibility of sending the 'response' (say as JSON) also to this Service JVM ?

I dont think 'AsyncContext' can be passed meaningfully outside of the Servlet container JVM. So, how to really delegate request-processing and response-sending, to be done by distributed services (JVMs) ?

In terms of code/pseudo-code, my question is:

@WebServlet(urlPatterns = "/AsyncServlet", asyncSupported=true)
public class AsyncServlet extends HttpServlet {

    protected void doGet(HttpServletRequest request,
            HttpServletResponse response)
        throws ServletException, IOException {

        AsyncContext asyncCtx = request.startAsync();
        // Put the asyncCtx in a JMS queue so as to be picked by another 
        // service JVM that can really service this request.
        // return back to receiving requests and dont worry abt sending a response
        // The service JVM will take care of sending the appropriate response
        // as it has the data necessary for the response.
    }
}

One option seems to be to have Worker threads (in the Servlet container JVM) wait for responses from the Service JVMs. After a Service JVM does the actual processing, it can communicate the results (thru messages or otherwise) to the respective Worker thread, and have the Worker thread send the GET response.

I want to know if there is (am sure there shd be !) a better alternative than this, as this seems so convoluted !


Solution

    1. Set context as async
    2. Store context inside singleton bean
    3. Send a jms request
    4. Process jms request
    5. Send jms reply
    6. Get context for reply from the singleton bean
    7. Send reply to client

    You might want to set a timer for cleanup and you can replace jms with async one-way ejb calls