hyper
hyper copied to clipboard
provide ability to request a fresh connection
Is your feature request related to a problem? Please describe. Certain retry behaviors specify a fresh connection (and sometimes a full DNS re-lookup) to direct traffic away from what might be a problematic host. I need the ability to somehow mark a request to Hyper as not reusing a connection that may be in the pool
Describe the solution you'd like I can imagine a few ways the API might be structured, but in general I'd like some way as marking a request as "needs fresh connection", potentially giving a reference to the old connection / response which was problematic.
Describe alternatives you've considered I could rebuild the entire client & pool when a request fails in a way that necessitates a re-lookup. However, it seems like that may cause unnecessary churn on the client side.
Additional context https://docs.aws.amazon.com/AmazonS3/latest/userguide/optimizing-performance-design-patterns.html#optimizing-performance-timeouts-retries
I forgot to comment this, but one possible way to do this could be to add an extension type (maybe hyper::client::connect::Fresh? Like CURLOPT_FRESH_CONNECT?) that you add to the request extensions, and if present, the client skips checking the pool.
But it may help to hear from anyone else who has needed a similar feature.
I like the idea of having hyper::client::connect::Fresh. Usage could look something like:
use hyper::client::connect::Fresh;
let req = Request::builder()
.method("GET")
.uri("https://example.com")
.extension(Fresh)
.body(())?;
let resp = client.request(req).await?;
This would work for our use-case where we need a new connection on retry since we can just add the Fresh extension as part of our Tower retry policy.
I'm not really sure how this would carry over to hyper 1.0 yet though. From reading the code, it looks like the connection pool was moved to hyper-util, but I can't find any client code that actually references it.
This feature would be really helpful to my team too - one thing we've seen is that we can have stale connections that just don't work anymore or the host they're connected to on the backend had some problem. It'd be nice if the Fresh extension didn't just bypass the lookup in the conn-pool but was a way to force the expiration and replacement of the existing pool in the connection.
@tjandra-amzn - That seems like a good idea to me.
I talked to @rcoh about this, and he had an interesting idea about having the PoolClient place an extension in responses that identifies the Key in the connection pool used to produce that response. Then a method could be added to client to evict the connections for a given response.
Thinking about that more, in the case where DNS starts responding with a new IP, I wonder if it would be better to evict only the connection that failed rather than all the connections with the same key, as there could be some newer connections in the pool that are still good.
To accomplish that, each PoolClient's connection info could add an extension value unique to that connection to each response so that the individual connection from the pool could be identified and evicted. Or, perhaps this extension value could be the resolved IP address so that all the connections for that given IP could be evicted?
@seanmonstar, what do you think about this approach?
@jdisanti That sounds like a good idea to me - we probably want to be invalidating as few connections as possible to prevent concerted storms of new connection attempts if the backing endpoint is partially available which the proposal would help with.
I think the general approach sounds reasonable. It kind of sounds like 2 separate (though related) features. So, it's probably easier to review and merge them separately. But I'm excited at the notion, making the pool more configurable/controllable is part of why I wanted to move it into hyper-util at first. There's lots of things to explore, and it shouldn't be hindered by "but should that API be frozen in place?"