Asynchronous JAX-RS: basics & gotchas

This blog post covers

Man, I tend to blog a lot about JAX-RS and REST !

Basics of server side async JAX-RS

On the server side, asynchronous behaviour is driven by

  • @Suspended: annotation which instructs the container to inject an instance of AsyncResponse and invoke the method asynchronously
  • AsyncResponse: bridge between the application logic and the client request

Since we have clearly expressed our asynchronous requirements, the container will ensure that

  • the calling thread is released
  • the actual business logic is executed in a different thread (in this case its the thread pool taken care of the by the Managed Executor Service in the Java EE container – thanks to Concurrency Utilties in Java EE 7)

Things to watch out for .. a.k.a gotchas

Although the calling (request) thread is released, the underlying I/O thread still blocks until the processing in background thread continues.In the above example, the caller would have to wait 5 seconds since that’s the delay we have purposefully introduced within the code. In simple words, the client (e.g. browser executing a HTTP GET) keeps waiting  until the business logic execution is finished by calling the resume method of the injected AsynResponse object (remember, it’s the bridge b/w the application & the client).

Timeouts to the rescue

One can specify a time out period after which the client gets back a HTTP 503 Service Unavailable response (default convention)

Fine grained time outs

The default behaviour (HTTP 503 on time out) might not be suitable for all use cases. For example, you might want to implement a solution where a tracking identifier needs to be sent to the client (for future) if the actual processing does not finish in due time (before timeout triggers). Having the ability to send a custom HTTP response on time out can prove useful. The AsyncResponse API makes this possible via the notion of a time out handler. You can do this by

  • a direct HTTP response (see below example)
  • via an exception (by passing an instance of Throwable to AsyncResponse#resume)

Client side async using the JAX-RS Client API

Using asynchronous behaviour on the client side is pretty easy. All you need to do is obtain an instance of AsyncInvoker by calling async on the Invocation.Builder

Above gotchas applicable here

As you might have already observed, async behaviour in (server side) JAX-RS is not the same as in other typical async APIs i.e. the client is still blocked.

  • You should use the async method (as demonstrated above) to call a server side REST API in an async manner even if the server REST API itself is asynchronous in nature (implemented using @Suspended AsyncResponse) .

I repeat: do not be under the impression that just because the server API is async, your client thread will return immediately

  • The call to async returns an instance of Future object – and you might already know, the get method (of Future)  blocks. So use it with care and at the correct point in your application logic

Further reading

That’s all. Be async. Be safe



About Abhishek

Loves Go, NoSQL DBs and messaging systems
This entry was posted in Java EE and tagged , , , , . Bookmark the permalink.

1 Response to Asynchronous JAX-RS: basics & gotchas

  1. Pingback: Nuances of JAX-RS client side async callback | Thinking in Java EE (at least trying to!)

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s