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?
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
>