For asynchronous programming, Jersey (JAX-RS) provides a ConnectionCallback
callback that is to be executed when a connection is broken. From the Jersey docs:
As some async requests may take long time to process the client may decide to terminate its connection to the server before the response has been resumed or before it has been fully written to the client. To deal with these use cases a ConnectionCallback can be used. This callback will be executed only if the connection was prematurely terminated or lost while the response is being written to the back client. Note that this callback will not be invoked when a response is written successfully and the client connection is closed as expected.
Sounds great, but I can never get this to fire.
Here's some code:
@GET
@Produces(MediaType.TEXT_PLAIN)
@ManagedAsync
@Path("/poll")
public void poll(@Suspended final AsyncResponse asyncResponse) {
asyncResponse.register(new CompletionCallback() {
@Override
public void onComplete(Throwable throwable) {
logger.info("onComplete called.");
}
});
asyncResponse.register(new ConnectionCallback() {
@Override
public void onDisconnect(AsyncResponse disconnected) {
logger.info("onDisconnect called.");
}
});
asyncResponse.setTimeout(POLL_TIMEOUT_SECONDS, TimeUnit.SECONDS);
asyncResponse.setTimeoutHandler(new TimeoutHandler() {
@Override
public void handleTimeout(AsyncResponse asyncResponse) {
logger.info("handleTimeout called.");
asyncResponse.resume(Response.status(Response.Status.OK).entity("TIMEOUT").build());
}
});
}
The other two callbacks shown, CompletionCallback and TimeoutHandler, fire just fine, without fail. If the specified timeout duration is reached, TimeoutHandler fires. If an AsyncResponse instance is resumed, CompletionCallback fires.
However, with ConnectionCallback, I can close, kill, or otherwise stop the client that is sitting connected to the web service shown above, and ConnectionCallback never gets fired.
Am I missing something? Is ConnectionCallback implemented in Jersey? (It's optional in the JAX-RS spec, but the Jersey docs talk about it as though it's implemented.)
Any input would be appreciated.