diff options
author | Yuchen Wu <[email protected]> | 2024-07-26 16:16:24 -0700 |
---|---|---|
committer | Andrew Hauck <[email protected]> | 2024-08-09 14:30:49 -0700 |
commit | 11b5882a422774cffbd14d9a9ea7dfc9dc98b02c (patch) | |
tree | 90537d2ed1ed9669143b2cee4d0a5483a9c3e56e | |
parent | 2a080423cd1b16f27d9ce338ae8fae35364a7fe9 (diff) | |
download | pingora-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-- | .bleep | 2 | ||||
-rw-r--r-- | pingora-core/src/protocols/http/v2/client.rs | 18 |
2 files changed, 16 insertions, 4 deletions
@@ -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 |