For example, my server handle a request cost 5 seconds, but the client stop waiting and cancel this request in 2 seconds, the 3 seconds left would be a waste, how can server know that and stop the handling process?
And I'm using Java Spring, is it possible to do this?
And If not, is there any good way to handle this case of waste caused by client cancelling?
It is possible, but depends on many things.
HTTP/1.1 does not have an explicit mechanism to tell the server to interrupt a request processing, other than closing the connection.
However, the server application is typically not reading from the connection to detect the close during the processing, so even if the client closes the server application won't notice.
HTTP/2 and HTTP/3 do have an explicit mechanism to tell the server to interrupt a request processing.
Unfortunately, Servlets (and by extension to JAX-RS) do not have any API that allows applications to be notified of clients sending a "reset stream" frame.
As Spring wraps Servlets and JAX-RS, unlikely you will have this API available, unless you want to bind to low-level, container-specific APIs, that allows your application to be notified of the "reset stream" event.
[Disclaimer, I am a Jetty committer]
When using Jetty you can use the low-level HTTP/2 APIs and be notified of such event.
For example:
ServerSessionListener sessionListener = new ServerSessionListener()
{
@Override
public Stream.Listener onNewStream(Stream stream, HeadersFrame frame)
{
// Process the request.
MetaData.Request request = (MetaData.Request)frame.getMetaData();
...
// Return a stream listener that can handle stream resets.
return new Stream.Listener()
{
...
@Override
public void onReset(Stream stream, ResetFrame frame, Callback callback)
{
// Handle stream reset from the client.
...
callback.succeeded();
}
}
}
}