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: Wed, 12 Aug 2009 10:04:10 -0700

Will there be a way for the client request filter to establish context
that the client response filter can in turn consume?


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
>