-
Notifications
You must be signed in to change notification settings - Fork 2.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support connection reset on cancellation for generated REST clients #41971
Comments
/cc @cescoffier (rest-client), @geoand (kotlin,rest-client) |
Thanks, I'll have a look next week |
@cescoffier @vietj what is the proper way to close / cancel an in flight request from the Vertx HTTP Client? |
You cannot cancel a request, you must close the connection. Be very careful with that, as it breaks keep-alive, and if http/2 with streams is used, you close all of them. Reset is also a possibility, but consequences are almost similar (I think you save the handshake, I. Red to double check) |
Resetting seems to be at the stream level. Wondering what happens for http/1 |
Ok, So for http/1 reset closes the connection (and thus may require another connection handshake later). For http/2 it reset the stream (using the infamous RST_STREAM frame). The server will receive the info and close the stream eventually (which means that it does not guarantee that the server will stop the work immediately or even that you won't receive the answer). The connection is still established and the other streams are not impacted. |
Thanks for the detailed response! So it sounds to me like we should probably shy away from reacting to the cancelation of a |
Is there a way to find out if a stream has no subscribers? In that situation, I think the right thing to do is close the connection in http/1 and reset the stream in http/2. This should match many other clients including OkHttp and the JDK clients when using: // future is a CompletableFuture<T> from: client.sendAsync()...
future.cancel(true); I believe .NET's HTTP client does the same thing as well. So does JavaScript's fetch. |
I'd imagine this change would go in the ClientSendRequestHandler's Lines 89 to 90 in 1f69d1d
However, I'm unsure of how to listen to the Mutiny reactive stream subscriber disconnecting from the stream...other than that, the change would be trivial for me to contribute. |
Maybe adding a cancel handler runnable to the request context would work? Then when Quarkus hands the user a Uni, it will have configured the cancellation. Given the following client: @Path("/long")
@RegisterRestClient
public interface HelloClient {
@GET
@Path("a")
@Produces(MediaType.TEXT_PLAIN)
Uni<String> longRunning();
} Maybe it's possible to have the returned uni hooked up to run: // uni is what would have originally been returned when calling longRunning()
uni.onCancellation().invoke(() -> {
// call previously set cancel handler runnable to reset the connection
}); |
Yeah, that would be the way to go, but we need to determine whether actually trying to close the connection is the right thing to do. |
Can it be made into an option like |
Likely yeah |
@calebkiage can you give #41990 a quick shot? |
Description
In PR #41710, cancellation support was added to the reactive REST services. However, the generated REST clients were never updated to support the scenario. What this means is that if the REST clients are used to call reactive endpoints, then the server will never be notified of the cancellation and will keep running the request to completion.
I have a sample project showing this issue attached below.
In the project, calling:
will reset the connection and the service will stop processing, but calling:
will not.
Sample project
Implementation ideas
The code below adds cancellation for a Vert.x HttpClient:
The text was updated successfully, but these errors were encountered: