I have a JAX-RS asynchronous API for long-term clients assembled in a Jersey 2.22 Container Container and hosted on Tomcat 7 .
It looks like the snippet shown below. It works well in production.
On average, 150 requests per long request are executed simultaneously. This results in almost the same number of Tomcat live HTTP connections (according to the JMX metric). A simple HTTP-BIO server was used for this low-traffic scenario . It is not possible to detect a connection leak at runtime if you use only managed threads :)
@Path("/v1/events")
public class LiveEventsResource {
private static final long longPollTimeoutMs = 30000;
private ExternalResource externalResource = ExternalResourceProvider.provide();
private AsyncResponse asyncResponse;
@POST
@Path("/liveEvents")
@ManagedAsync
public void getResult(@Suspended final AsyncResponse asyncResponse, RequestPayload payload) {
this.asyncResponse = asyncResponse;
asyncResponse.setTimeout(longPollTimeoutMs, TimeUnit.MILLISECONDS);
asyncResponse.setTimeoutHandler(new TimeoutHandler() {
@Override
public void handleTimeout(AsyncResponse asyncResponseArg) {
try {
asyncResponseArg.cancel();
} finally {
cleanupResources();
}
}
});
startListeningForExternalEventsAndReturn(payload);
}
private void startListeningForExternalEventsAndReturn(RequestPayload payload) {
externalResource.register(new Listener() {
@Override
public void onEvent(Event event) {
respond(event);
}
});
}
private void respond(Event event) {
try {
asyncResponse.resume(event);
} catch (RuntimeException exception) {
asyncResponse.resume(exception);
} finally {
cleanupResources();
}
}
protected void cleanupResources() {
externalResource.cleanup();
}
}
, , , Tomcat , -, 300, 450, maxConnection , .
API , - (, , , , ), API. .
. undeployment ( TimeOutHandler) ( ), . , () asnyc-, , JVM!
, , , , AsyncResponse (AsyncResponder) - ( JQL, Classloader). , org.apache.coyote.Request.
, Jersey Container, , - , @PreDestroy -time close() dispose() Provider s.
, TimeOutHandler, undeployment . @BackgroundScheduler (DefaultBackgroundSchedulerProvider) TimeOutHandler Executor , , AsyncResponse.resume() AsyncResponse.cancel() . , .
, , ?