X

Pavel Bucek's Weblog

  • June 28, 2011

Jersey non blocking client

Although Jersey
already have support for making asynchronous requests, it is
implemented by standard blocking way - every asynchronous request is
handled by one thread and that thread is released only after request is
completely processed. That is OK for lots of cases, but imagine how that
will work when you need to do lots of parallel requests. Of course you
can limit (and its really wise thing to do, you do want control your
resources) number of threads used for asynchronous requests, but you'll
get another maybe not pleasant consequence - obviously processing time
will increase.

There are few projects which are trying to deal
with that problem, commonly named as async http clients. I didn't want
to "re-implement a wheel" and I decided I'll use AHC - Async Http Client made by Jeanfrancois Arcand. There is also interesting implementation from Apache - HttpAsyncClient, but it is still in "very early stages of development" and others haven't been in similar or better shape as AHC.

How
this works? Non-blocking clients allow users to make same asynchronous
requests as we can do with standard approach but implementation is
different - threads are better utilized, they don't spend most of time
in idle state. Simply described - when you make a request (send it over
the network), you are waiting for reply from other side. And there comes
main advantage of non-blocking approach - it uses these threads for
further work, like making other requests or processing responses etc..
Idle time is minimized and your resources (threads) will be far better
used.

Who should consider using this? Everyone
who is making lots of asynchronous requests. I haven't done proper
benchmark yet, but some simple dumb tests are showing huge improvement
in cases where lots of concurrent asynchronous requests are made in
short period.

Last but not least - this module is still
experimental, so if you don't like something or if you have ideas for
improvements/any feedback, feel free to comment this blog post, send
mail to users@jersey.java.net or contact me personally. All feedback is greatly appreciated!

maven dependency (will be present in java.net maven 2 repo by the end of the day):

link: http://download.java.net/maven/2/com/sun/jersey/experimental/jersey-non-blocking-client

<dependency>
<groupId>com.sun.jersey.experimental</groupId>
<artifactId>jersey-non-blocking-client</artifactId>
<version>1.9-SNAPSHOT</version>
</dependency>

code snippet:

 ClientConfig cc = new DefaultNonBlockingClientConfig();
cc.getProperties().put(NonBlockingClientConfig.PROPERTY_THREADPOOL_SIZE, 10); // default value, feel free to change
Client c = NonBlockingClient.create(cc);
AsyncWebResource awr = c.asyncResource("http://oracle.com");
Future<ClientResponse> responseFuture = awr.get(ClientResponse.class);
// or
awr.get(new TypeListener<ClientResponse>(ClientResponse.class) {
@Override
public void onComplete(Future<ClientResponse> f) throws InterruptedException {
...
}
});

javadoc (temporary location, won't be updated): http://anise.cz/~paja/jersey-non-blocking-client/

Join the discussion

Comments ( 15 )
  • walec51 Thursday, June 30, 2011

    fantastic !

    I've bean waiting for this feature


  • guest Thursday, June 30, 2011

    Now that there is true non-blocking http client, the next logical step might be trying non-blocking processing. Fortunately for XML there is Aalto (http://wiki.fasterxml.com/AaltoHome), so parsing can be done in non-blocking way (and very fast, at that!).

    But I don't know if there is a non-blocking data-binding lib available: JAXB might not be awfully hard to change, since it uses event-based approach (due to starting with SAX), but it won't work without some changes.


  • Pavel Thursday, October 11, 2012

    Hi Pavel,

    Did the implementation of the non blocking client moved from experimental to production?

    It does not look like that the onComplete called from within the client. Or it does require an additional settings of the client?

    Best regards,

    Pavel


  • guest Friday, November 23, 2012

    Hi Pavel,

    i am wondering why after i implemented your client codes, my server always return HTTP 400.

    i am using these following codes on my client code:

    FormDataMultiPart part = new FormDataMultiPart();

    part.field("max_accepted_LTT", max_accepted_LTT.toString(), MediaType.APPLICATION_XML_TYPE);

    part.field("hasAttachments", hasAttachments.toString(), MediaType.APPLICATION_XML_TYPE);

    GenericType<InputStream> genericType = new GenericType<InputStream>() {};

    Future<InputStream> lttResult = asr.path("getDALTT").type(MediaType.MULTIPART_FORM_DATA_TYPE).post(genericType, part);

    and for the server side, im using these codes:

    @POST

    @Path("getDALTT")

    @Consumes(MediaType.MULTIPART_FORM_DATA)

    public InputStream getDALTT(@FormDataParam("max_accepted_LTT") String max_accepted_LTT, @FormDataParam("hasAttachments") String hasAttachments) throws IOException {

    logger.info("request accepted");

    }

    Kindly advise


  • Pavel Friday, November 23, 2012

    https://blogs.oracle.com/PavelBucek/entry/jersey_non_blocking_client#comment-1349988917812

    Hi Pavel,

    non-blocking client is already moved to contribs and few related issues were fixed since then, can you please retest with Jersey 1.15?


  • Pavel Friday, November 23, 2012

    https://blogs.oracle.com/PavelBucek/entry/jersey_non_blocking_client#comment-1353667832861

    Hi,

    can you please strip down multipart from your code and try again? I'm not sure whether it is handled well when async client is used.


  • guest Friday, November 23, 2012

    Hi Pavel,

    I sent you a message through jersey forum.

    Thanks in advance

    s3v3nth


  • Pavel Tuesday, November 27, 2012

    Hi Pavel,

    I only experienced the issue while running Unit Tests. It works fine outside of the Unit Test.

    Best regards,

    Pavel


  • guest Monday, March 25, 2013

    Hi Pavel!

    I found that you one of authors of com.sun.jersey.client.impl.CopyOnWriteHashMap. It takes 30 seconds to look at the code to understand that the class in not multithreaded and can throw ConcurrentModificationException. You can modify the "copy" field collection having an iterator on the object. I don't know where to submit bugs against the code, so writing here, please fix.


  • Pavel Tuesday, April 2, 2013

    Hi guest,

    please file new issue against Jersey: http://java.net/jira/browse/JERSEY , ideally with a (failing) testcase.

    Thanks!

    Pavel


  • guest Monday, April 21, 2014

    Is it possible to implement this (non-blocking client) for Jersey 2.4.1 version?


  • guest Wednesday, April 30, 2014

    I believe that JAX-RS client already works in non-blocking mode; please see https://jersey.java.net/documentation/latest/async.html#d0e8916


  • guest Thursday, May 1, 2014

    Many Thanks for the reply. I didn't notice that. May be I should read the user documentation completely.


  • Niranjan Monday, September 1, 2014

    I am not able to locate the AHC link on github. I believe the user has deleted his account. Need the code very urgently as I have to deliver the solution to my client ASAP.

    I need to call JSON service asynchronously.


  • guest Monday, September 1, 2014

    @Niranjan: asynchronous != non-blocking.

    You can call the service asynchronously with Jersey 1 client or JAX-RS 2.x client .. so there is the problem?

    See https://jersey.java.net/documentation/latest/async.html for JAX-RS 2.x client info or https://jersey.java.net/apidocs/1.18/jersey/com/sun/jersey/api/client/Client.html#asyncResource(java.net.URI) for Jersey 1.x


Please enter your name.Please provide a valid email address.Please enter a comment.CAPTCHA challenge response provided was incorrect. Please try again.