users@jersey.java.net

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

From: Craig McClanahan <Craig.McClanahan_at_Sun.COM>
Date: Wed, 12 Aug 2009 14:43:20 -0700

Paul Sandoz wrote:
>
> On Aug 12, 2009, at 7:59 PM, 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, Paul, which of the following options do you think is best ?
>
> 1) breaking changes to all filters, requiring that developers change
> their filter code; or
>
> 2)
> non-breaking changes, but any stack-based only filters utilized with an async request will result in non-optimal use
> of threads (if an HTTP client is capable of optimal async requests).
>
> I am leaning towards option 2.
#1 would be really nasty -- there's probably *way* too many existing
filter implementations in the world to contemplate this without going
through a major version change or something.

Craig

>
> Paul.
>
>
>> 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
>>>
>>>
>>
>