Hi,
After Marc sent a link to the JAX-WS async interfaces i also had some
discussion with Brian Goetz and the advice was it is better to pass a
Future to the listener as well as return a Future (the two may be the
same instance but does not have to be). So i have changed the
listeners to use a Future.
The low-level interfaces are at the end of the email and should now be
suitable for plugging into an async implementation.
The high-level way of async listening is as follows:
AsyncWebResource r = ..
Future<String> f = r.get(new TypeListener<String>(String.class) {
public void onComplete(Future<String> f) throws
InterruptedException {
try {
String s = f.get();
} catch (ExecutionException ex) {
// Do error processing
if (t instanceof UniformInterfaceException) {
// Request/response error
} else
// Error making request e.g. timeout
}
} catch (CancellationException ex) {
// Clean up on cancellation
}
// InterruptedException will never be thrown because the
Future is completed
}
});
The returned Future<String> instance can be used to cancel the request
and the listener will get invoked. A call to Future.get in the
listener will result in a CancellationException being thrown.
Paul.
/**
* An asynchronous client handler for invoking asynchronous client
requests.
*
* @author Paul.Sandoz_at_Sun.Com
*/
public interface AsyncClientHandler {
/**
* Invoke an asynchronous client request. This method returns
without
* waiting for the client response.
*
* @param r the client request.
* @param l the future listener to receive a completed Future
with the
* client response.
* @return a future that may be used to wait until the future
completes and
* obtain the client response state, or cancel the request.
*/
Future<ClientResponse> handle(ClientRequest r,
FutureListener<ClientResponse> l);
}
/**
* A future listener to receive an event when a Future has reached the
* completed termination state of normal termination, an exception
* or cancellation.
*
* @param <T> the type held by the future.
* @author Paul.Sandoz_at_Sun.Com
*/
public interface FutureListener<T> {
/**
* Invoked when a Future has reached the completed termination
state.
* <p>
* The catching of a {_at_link ExecutionException} when
* <code>Future.get</code> is invoked may be utilized to
determine if the
* future terminated with an exception. The exception can be
obtained
* by invoking {_at_link ExecutionException#getCause() }.
* <p>
* The catching of a {_at_link CancellationException} when
* <code>Future.get</code> is invoked may be utilized to
determine if the
* future terminated with a cancellation.
*
* @param f the completed Future. Invocation of {_at_link
Future#isDone() }
* will return true. Since the future is complete
invocation of
* {_at_link Future#get() } and {_at_link Future#get(long,
java.util.concurrent.TimeUnit) }
* will not result in the throwing of an {_at_link
InterruptedException}.
* @throws InterruptedException this exception is declared so
that the
* developer does not need to catch it when invoking
* <code>Future.get</code>.
*/
void onComplete(Future<T> f) throws InterruptedException;
}