Over a million developers have joined DZone.

Handling Time Outs in Async Requests in JAX-RS

· Java Zone

What every Java engineer should know about microservices: Reactive Microservices Architecture.  Brought to you in partnership with Lightbend.

JAX-RS 2.0 provides support for asynchronous programming paradigm, both on client as well as on the server end. This post which highlights the time out feature while executing asynchronous REST requests on server side using the JAX-RS (2.0) API

Without diving into too many details here is a quick overview. In order to execute a method in asynchronous fashion, you just

  • need to specify an instance of AsyncResponse interface as one of the method parameters
  • annotate it using using the @Suspended annotation (JAX-RS will inject an instance of AsyncResponse for you whenever it detects this annotation)
  • need to invoke the request in a different thread – recommended way to do this in Java EE 7 is to use Managed Service Executor
@GET
@Produces("text/plain")
public void execute(@Suspended AsyncResponse response){
    System.out.println("Initially invoked on thread - "+ Thread.currentThread.getName() + ". This will free up soon !");
    new Thread(){
        @Override
        public void run(){
            response.resume("executed asynchronously on thread - "+ Thread.currentThread.getName());
        }
    }.start();
}

//JDK 8 version - passing a Runnable (in form of a Lambda Expression) to a thread

@GET
@Produces("text/plain")
public void execute(@Suspended AsyncResponse response){
    System.out.println("Initially invoked on thread - "+ Thread.currentThread.getName() + ". This will free up soon !");
    new Thread(() -> response.resume("executed asynchronously on thread - "+ Thread.currentThread().getName())).start();
}

Behind the scenes ??

The underlying I/O connection b/w the server and the client continues to remain open. But there are scenarios where you would want not want the client to wait for a response forever. In such a case, you can allocate a time out (threshold)

The default behavior in case of a time out is a HTTP 503 response. In case you want to override this behavior, you can implement a TimeoutHandler and register it with your AsyncResponse. In case you are using Java 8, you need not bother with a separate implementation class or even an anonymous inner class – you can just provide a Lambda Expression since the TimeoutHandler is a Functional Interface with a Single Abstract Method

@GET
@Produces("text/plain")
public void execute(@Suspended AsyncResponse response){
    System.out.println("Initially invoked on thread - "+ Thread.currentThread.getName() + ". This will free up soon !");
    //just having this would result in HTTP 503 after 10 seconds
    response.setTimeout(10, TimeUnit.SECONDS); 
    //client will recieve a HTTP 408 (timeout error) after 10 seconds
    response.setTimeoutHandler((asyncResp) -> asyncResp.resume(Response.status(Response.Status.REQUEST_TIMEOUT)).build());
    new Thread(() -> {
                try {
                    Thread.sleep(11000);
                } catch (InterruptedException ex) {
                   //ignoring
                }
            }).start();
}


Microservices for Java, explained. Revitalize your legacy systems (and your career) with Reactive Microservices Architecture, a free O'Reilly book. Brought to you in partnership with Lightbend.

Topics:

Published at DZone with permission of Abhishek Gupta, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

The best of DZone straight to your inbox.

SEE AN EXAMPLE
Please provide a valid email address.

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.
Subscribe

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}