users@jersey.java.net

[Jersey] Re: Async client and Response.readEntity

From: Mikael Ståldal <mikael.staldal_at_appearnetworks.com>
Date: Thu, 22 Jan 2015 18:34:36 +0100

> 1. InvocationCallback<Order> is run from some other thread (i.e.
asynchronously) that has issued the request

Yes, so far so good. But then I cannot access the response metadata (HTTP
status, response headers).

> 2. The callback is only invoked AFTER the
Response.readEntity(Order.class) has completed. So having an
InvocationCallback<Response> and invoking Response.readEntity(..) inside is
not making things worse.

So if I do like this:

Invocation invocation = client.target(someURL).request().buildGet();
invocation.submit(new InvocationCallback<Response> {
    public void completed(Response response) {
        int statusCode = response.getStatus();

        Order order = response.readEntity(Order.class); // blocking?
      process(statusCode, order);
    }
    public void failed(Throwable throwable) {
        error();
    }
});


It will not block on I/O when invoking response.readEntity(Order.class)?
If so, my understanding of how it works was wrong, and the issue is invalid.

> Perhaps you are looking for a non-blocking I/O API support

I am, but this particular issue is not really about that.

> Something like Response.readEntity(Order.class, order -> { … }) ?

If it works the way you say (Response.readEntity is non-blocking since it
just return something which has already been read, parsed and buffered in
memory), that shouldn't be necessary.

> Btw. do you know that you can easily check the response code from a
JAX-RS ClientResponseFilter
<https://jax-rs-spec.java.net/nonav/2.0-rev-a/apidocs/javax/ws/rs/client/ClientResponseFilter.html>
 ?

To me, it seems quite clumsy if I would have to use a filter in this use
case.


On Thu, Jan 22, 2015 at 1:42 PM, Marek Potociar <marek.potociar_at_oracle.com>
wrote:

> Hi Mikael,
>
> Please see inline.
>
> On 12 Jan 2015, at 11:29, Mikael Ståldal <
> mikael.staldal_at_appearnetworks.com> wrote:
>
> No, I did not get any answer to this. And neither to the JIRA issues I
> have filed:
>
> https://java.net/jira/browse/JERSEY-2682
>
>
> C&Ping my comment from the issue:
>
> I have looked at the issue and I’m not sure I understand the problem you
> are pointing out:
>
> 1. InvocationCallback<Order> is run from some other thread (i.e.
> asynchronously) that has issued the request
> 2. The callback is only invoked AFTER the Response.readEntity(Order.class)
> has completed. So having an InvocationCallback<Response> and invoking
> Response.readEntity(..) inside is not making things worse.
>
> Perhaps you are looking for a non-blocking I/O API support, which is
> planned for the next release of JAX-RS
> <https://jcp.org/en/jsr/detail?id=370>? Something like
> Response.readEntity(Order.class, order -> { … }) ?
> Btw. do you know that you can easily check the response code from a JAX-RS
> ClientResponseFilter
> <https://jax-rs-spec.java.net/nonav/2.0-rev-a/apidocs/javax/ws/rs/client/ClientResponseFilter.html>
> ?
>
>
> To me, it seems like the async part of the JAX-RS 2.0 client API is flawed
> (not to mention the default implementation in Jeresy:
> https://java.net/jira/browse/JERSEY-2058).
>
>
> The primary problem is in lack of NIO support in the current JAX-RS API.
> We’re looking into fixing it for the next JAX-RS release, as noted above.
> Obviously, we will first try to make it work in Jersey, so Jersey users
> should have a working solution long before JAX-RS.next is released. I do
> not have any ETA at this point though.
>
>
> It's a pity, since the synchronous client API in JAX-RS 2.0 (and its
> implementation in Jersey) is really nice.
>
> I am considering using something else for async REST client, such as
> https://github.com/AsyncHttpClient/async-http-client or Jetty client.
>
>
> FWIW, our grizzly connector is actually wrapped into async HTTP client
> API. But again, current lack of NIO support in JAX-RS APIs is making it
> difficult to come up with a good async client solution. That said, we’re
> already trying, stay tuned.
>
> Marek
>
>
> On Wed, Dec 31, 2014 at 9:06 PM, Robert DiFalco <robert.difalco_at_gmail.com>
> wrote:
>
>> Did you ever get an answer to this?
>>
>> On Mon, Oct 6, 2014 at 7:45 AM, Mikael Ståldal <
>> mikael.staldal_at_appearnetworks.com> wrote:
>>
>>> Consider using Jersey client in async mode with an
>>> InvocationCallback<Response>, and then use readEntity() on the Response.
>>> Order is a custom domain object for which we have a MessageBodyReader
>>> available.
>>>
>>> Invocation invocation = client.target(someURL).request().buildGet();
>>> invocation.submit(new InvocationCallback<Response> {
>>> public void completed(Response response) {
>>> int status = response.getStatus();
>>> if (status == 200) {
>>> Order order = response.readEntity(Order.class); // blocking ?
>>> process(order);
>>> } else {
>>> error();
>>> }
>>> }
>>> public void failed(Throwable throwable) {
>>> error();
>>> }
>>> });
>>>
>>> Is the response.readEntity() call blocking? Is it I/O bound if the
>>> response is large? Or is the whole response read from network before the
>>> completed() callback is invoked?
>>>
>>> Will the asynchronicity be improved if I do InvocationCallback<Order>
>>> instead? What if I want to get other information from the Response?
>>>
>>> --
>>> Mikael Ståldal
>>> Chief Software Architect
>>> *Appear*
>>> Phone: +46 8 545 91 572
>>> Email: mikael.staldal_at_appearnetworks.com
>>>
>>
>>
>
>
> --
> Mikael Ståldal
> Chief Software Architect
> *Appear*
> Phone: +46 8 545 91 572
> Email: mikael.staldal_at_appearnetworks.com
>
>
>


-- 
Mikael Ståldal
Chief Software Architect
*Appear*
Phone: +46 8 545 91 572
Email: mikael.staldal_at_appearnetworks.com