users@jersey.java.net

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

From: Paul C. Bryan <pbryan_at_sun.com>
Date: Thu, 13 Aug 2009 15:32:46 -0700

Sounds good.

On Thu, 2009-08-13 at 11:47 +0200, Paul Sandoz wrote:
> On Aug 13, 2009, at 1:16 AM, Paul C. Bryan wrote:
>
> > I guess I'm in the minority.
> >
> > Another option might be to have a common base class for sync and async
> > client filter interfaces and when the filter is added, the specific
> > type
> > can be ascertained? This way new filters can be written efficiently,
> > old
> > filters can transition?
> >
>
> Yes, this is what i am proposing with:
>
> public abstract class ClientRequestResponseFilter extends
> ClientFilter ...
>
> Thus existing ClientFilter implementations will work. If a developer
> wants to transition such that a filter works efficiently for async
> operations then they will need to modify their filter to extend from
> ClientRequestResponseFilter and following the instructions in the
> JavaDoc.
>
> Paul.
>
> > Paul
> >
> > On Wed, 2009-08-12 at 14:43 -0700, Craig McClanahan wrote:
> >> 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
> >>>>>
> >>>>>
> >>>>
> >>>
> >>
> >>
> >> ---------------------------------------------------------------------
> >> 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
>