Issue
Problem
Jetty 9 based server is processing time consuming (30-60 sec) and computation heavy (~20 threads involved in parallel processing) requests.
Due to interactive nature, client may cancel HTTP request after few seconds and send a new one.
It is desirable to cancel computation immediately if connection has been closed by client.
Unsuccessful attempts
In case of closed HTTP connection, attempt to write to response output stream would trigger
IOException
. Though, in case of this application, HTTP status depends on result of whole computation so it is not possible to write anything back to socket in the middle of processing. Thus, this option is not applicable.Jetty have handy
HttpConnection.getCurrentConnection()
method which can be used to get references to some internal classes related to HTTP connection including underlyingSocketChannel
. Though I haven't found a way to check liveliness of connection thoughSocketChannel
or other Jetty's classes related to connection.
Solution
The best choice is to use the javax.servlet.AsyncContext
and its javax.servlet.AsyncListener
.
Start with a call to java.servlet.HttpServletRequest.startAsync()
to get the AsyncContext
.
Then add a custom AsyncListener
of your own, don't forget to also set a timeout on your AsyncContext
(as its existence overrides the default Idle Timeout mechanism)
You'll get events that mean something useful to you ...
- onComplete - the processing has completed
- onError - the processing has failed (such as a unexpected connection termination)
- onTimeout - the AsyncContext timeout has fired
This is the mechanism that the Servlet API has provided for exactly your situation: computation or backend heavy processing during an active request that might be terminated early.
Answered By - Joakim Erdfelt