users@jersey.java.net

Re: [Jersey] Proposed breaking changes for client API for efficient async support

From: Alex Sherwin <alex.sherwin_at_acadiasoft.com>
Date: Wed, 12 Aug 2009 16:10:36 -0400

When might we see this in a Jersey point release?

Craig McClanahan wrote:
> Paul C. Bryan wrote:
>> Okay, then FWIW, +1 from me. That's the least disruptive break I can
>> imagine for the switch to asynchronous... :)
>>
>>
> +1 as well. I'm not concerned about binary compatibility, as I'm
> always recompiling my apps anyway.
>
> Craig
>> On Wed, 2009-08-12 at 19:08 +0200, Paul Sandoz wrote:
>>
>>> On Aug 12, 2009, at 7:04 PM, Paul C. Bryan wrote:
>>>
>>>
>>>> Will there be a way for the client request filter to establish context
>>>> that the client response filter can in turn consume?
>>>>
>>>>
>>> Yes, properties can be added to the request in the request filter
>>> which can then be retrieved in the response filter:
>>>
>>> https://jersey.dev.java.net/nonav/apidocs/1.1.1-ea/jersey/com/sun/jersey/api/client/ClientRequest.html
>>> #getProperties%28%29
>>>
>>> Paul.
>>>
>>>
>>>> On Wed, 2009-08-12 at 14:45 +0200, Paul Sandoz wrote:
>>>>
>>>>> Hi,
>>>>>
>>>>> I mentioned before in a previous email about breaking changes client
>>>>> API to support efficient asynchronous requests/responses such that a
>>>>> response can be processed on a different thread to that of a request.
>>>>>
>>>>> The current filter approach is stack-based using a general handler
>>>>> chain where the last handler is "inflection" point that sends an HTTP
>>>>> request and produces an HTTP response.
>>>>>
>>>>> We need to split the a filter into separate request and response
>>>>> filters:
>>>>>
>>>>> public interface ClientRequestFilter {
>>>>> ClientRequest filter(ClientRequest request);
>>>>> }
>>>>>
>>>>> public interface ClientResponseFilter {
>>>>> ClientResponse filter(ClientRequest request, ClientResponse
>>>>> response);
>>>>> }
>>>>>
>>>>> Then we can have an abstract class as follows:
>>>>>
>>>>> public abstract class ClientFilter implements ClientRequestFilter,
>>>>> ClientResponseFilter {
>>>>> public ClientRequest filter(ClientRequest request) {
>>>>> return request;
>>>>> }
>>>>>
>>>>> public ClientResponse filter(ClientRequest request,
>>>>> ClientResponse response) {
>>>>> return response;
>>>>> }
>>>>> }
>>>>>
>>>>> and modify all existing filters supported by Jersey to extend from
>>>>> the
>>>>> new ClientFilter. That way we can ensure that existing source that
>>>>> uses the Jersey supplied filters to add instances to Client or
>>>>> WebResource is still compatible (i strongly suspect binary
>>>>> compatibility will be broken so a recompile would be required).
>>>>>
>>>>> The ClientHandler interface is still relevant for implementations of
>>>>> HTTP clients (HttpURLConnection, Apache HTTP clent, and in memory-
>>>>> client). But we will require an AsyncClientHandler to implement if
>>>>> async request/response processing is supported:
>>>>>
>>>>> public interface AsyncClientHandler {
>>>>> void handler(ClientRequest r, ClientResponseListener l);
>>>>> }
>>>>>
>>>>> public interface ClientResponseListener {
>>>>> void onError(Throwable t);
>>>>>
>>>>> void onResponse(ClientResponse cr);
>>>>> }
>>>>>
>>>>>
>>>>>
>>>>> After I wrote the above I realized there is the possibility for an
>>>>> alternative solution that will limit breaking changes to the async
>>>>> parts of the API. Thus existing filters used with the non-async parts
>>>>> will not be affected.
>>>>>
>>>>> It should be possible to retain the stack-based approach for non-
>>>>> async
>>>>> support and modify the existing filters to support stack and non-
>>>>> stack
>>>>> approaches by filters extending from the following class:
>>>>>
>>>>> public abstract class ClientRequestResponseFilter extends
>>>>> ClientFilter, ClientRequestFilter, ClientResponseFilter {
>>>>> public ClientResponse handle(ClientRequest request)
>>>>> throws ClientHandlerException {
>>>>>
>>>>> request = filter(request);
>>>>>
>>>>> response = getNext().handler(cr);
>>>>>
>>>>> return filter(response);
>>>>> }
>>>>>
>>>>> // state associated with request filter which needs to be
>>>>> accessed by response filter
>>>>> // must be added as a property on the request, a thread local
>>>>> cannot be used because
>>>>> // the response filter may be processed on a different thread to
>>>>> the request filter.
>>>>> public ClientRequest filter(ClientRequest request) {
>>>>> return request;
>>>>> }
>>>>>
>>>>> public ClientResponse filter(ClientRequest request,
>>>>> ClientResponse response) {
>>>>> return response;
>>>>> }
>>>>> }
>>>>>
>>>>> However there is an issue if instances of ClientFilter (that are not
>>>>> instances of ClientRequestResponseFilter) are added to the filter
>>>>> chain of Client, which are then utilized by a AsyncWebResource. This
>>>>> will render inoperable efficient async operation. Under such
>>>>> circumstances we could easily generate a warning.
>>>>>
>>>>> Paul.
>>>>>
>>>>> ---------------------------------------------------------------------
>>>>> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
>>>>> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>>>>>
>>>>>
>>>> ---------------------------------------------------------------------
>>>> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
>>>> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>>>>
>>>>
>>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
>>> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>>>
>>>
>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
>> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>>
>>
>