aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorYuchen Wu <[email protected]>2024-07-26 16:16:24 -0700
committerAndrew Hauck <[email protected]>2024-08-09 14:30:49 -0700
commit11b5882a422774cffbd14d9a9ea7dfc9dc98b02c (patch)
tree90537d2ed1ed9669143b2cee4d0a5483a9c3e56e
parent2a080423cd1b16f27d9ce338ae8fae35364a7fe9 (diff)
downloadpingora-11b5882a422774cffbd14d9a9ea7dfc9dc98b02c.tar.gz
pingora-11b5882a422774cffbd14d9a9ea7dfc9dc98b02c.zip
Retry all h2 connection when encountering graceful shutdown
Before this change, the retry only happens on reused connections. The shutting down could also happen on new connections as well. So this change will retry in both cases.
-rw-r--r--.bleep2
-rw-r--r--pingora-core/src/protocols/http/v2/client.rs18
2 files changed, 16 insertions, 4 deletions
diff --git a/.bleep b/.bleep
index 01e2f72..47acd39 100644
--- a/.bleep
+++ b/.bleep
@@ -1 +1 @@
-580a96a6280ded91caae0630a5d67d0564369f3f \ No newline at end of file
+a29925df89353fce33cd5a78459fc99c707f19ab \ No newline at end of file
diff --git a/pingora-core/src/protocols/http/v2/client.rs b/pingora-core/src/protocols/http/v2/client.rs
index 86a3fe3..9bdbff4 100644
--- a/pingora-core/src/protocols/http/v2/client.rs
+++ b/pingora-core/src/protocols/http/v2/client.rs
@@ -349,6 +349,19 @@ impl Http2Session {
if self.ping_timedout() {
e.etype = PING_TIMEDOUT;
}
+
+ // is_go_away: retry via another connection, this connection is being teardown
+ // should retry
+ if self.response_header.is_none() {
+ if let Some(err) = e.root_cause().downcast_ref::<h2::Error>() {
+ if err.is_go_away()
+ && err.is_remote()
+ && err.reason().map_or(false, |r| r == h2::Reason::NO_ERROR)
+ {
+ e.retry = true.into();
+ }
+ }
+ }
e
}
}
@@ -367,7 +380,7 @@ pub fn write_body(send_body: &mut SendStream<Bytes>, data: Bytes, end: bool) ->
/* Types of errors during h2 header read
1. peer requests to downgrade to h1, mostly IIS server for NTLM: we will downgrade and retry
2. peer sends invalid h2 frames, usually sending h1 only header: we will downgrade and retry
- 3. peer sends GO_AWAY(NO_ERROR) on reused conn, usually hit http2_max_requests: we will retry
+ 3. peer sends GO_AWAY(NO_ERROR) connection is being shut down: we will retry
4. peer IO error on reused conn, usually firewall kills old conn: we will retry
5. All other errors will terminate the request
*/
@@ -393,9 +406,8 @@ fn handle_read_header_error(e: h2::Error) -> Box<Error> {
&& e.reason().map_or(false, |r| r == h2::Reason::NO_ERROR)
{
// is_go_away: retry via another connection, this connection is being teardown
- // only retry if the connection is reused
let mut err = Error::because(H2Error, "while reading h2 header", e);
- err.retry = RetryType::ReusedOnly;
+ err.retry = true.into();
err
} else if e.is_io() {
// is_io: typical if a previously reused connection silently drops it