-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
fix(client): run connect_to
to completion even if ResponseFuture
is canceled
#3205
base: 0.14.x
Are you sure you want to change the base?
Conversation
…is canceled In the previous implementation the `connect_to` future was spawned to let it finish when the checkout future won the race. However, in the event of the user dropping the `ResponseFuture`, the `connect_to` future was canceled as well, and all the http2 requests waiting for the connection would error as a result. This commit prevents that by spawning the `connect_to` future invariably (once it starts) thus covering both cases. Fixes hyperium#3199
…is_inherited_by_next_request
I've chosen a slightly different approach than that suggested in #3199, and also taken the liberty to remove |
I think this still needs to be left in. It's there to prevent always starting a |
I thought the particularity of However if I'm not mistaken
|
@seanmonstar could you approve the workflow again please 🙏 ? |
I'm thinking through this... Is this true always? I'm thinking that at least in the HTTP/1 case, after grabbing the |
I misspoke in the previous comment. What you say is exactly how it behaves (also for http2), and it is precisely the reason I claim the |
Let me know how do you want to resolve this. If I haven't convinced you about the |
Sorry, I was wrapping up a few other things, and wanted to pay this more attention to be sure I understand, because I feel this is pretty subtle. I'll take another look! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, I see what you mean about the lazy. It's become a different form of lazy.
One downside with this is it requires spawning another task. Would it be possible to do this without a new task? Or would it require way too much juggling of the pool to get it to work?
return Either::Right(future::err(canceled)); | ||
} | ||
}; | ||
Either::Left(Box::pin(async move { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, I see, by putting the call to connector.connect()
inside this sub future, async move
, it won't call connect()
until the first poll. Got it.
tests/client.rs
Outdated
assert!( | ||
// The second response has not been canceled and it is still waiting for the connection | ||
// that will never arrive | ||
future::poll_fn(|ctx| Poll::Ready(Pin::new(&mut res2).poll(ctx).is_pending())).await |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But will it actually fulfill with the connection? It'd be good to test that. Otherwise, a lost future here would also make this test pass.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point. I've implemented the suggestion. Thanks!
I'll give it a try! |
In the previous implementation the
connect_to
future was spawned to let it finish when the checkout future won the race. However, in the event of the user dropping theResponseFuture
, theconnect_to
future was canceled as well, and all the http2 requests waiting for the connection would error as a result. This commit prevents that by spawning theconnect_to
future invariably (once it starts) thus covering both cases.Fixes #3199