diff options
author | Edward Wang <[email protected]> | 2024-10-04 00:24:49 -0700 |
---|---|---|
committer | Yuchen Wu <[email protected]> | 2024-10-11 16:52:23 -0700 |
commit | 894ca2dd64526c49a9adc43aa45a0a0f32743987 (patch) | |
tree | ee3ad689cbe747dadcc05fc4f1d8735226d9d553 /pingora-proxy | |
parent | 792d5fd3c14c1cd588b155ddf09c09a4c125a26b (diff) | |
download | pingora-894ca2dd64526c49a9adc43aa45a0a0f32743987.tar.gz pingora-894ca2dd64526c49a9adc43aa45a0a0f32743987.zip |
Don't reuse session when downstream errors during cache miss
When a downstream error occurs while a cache miss is being served, the
downstream error is ignored so the upstream can continue writing to the
cache. However, it is not safe to try reusing the server session in this
case.
Diffstat (limited to 'pingora-proxy')
-rw-r--r-- | pingora-proxy/src/proxy_h1.rs | 24 | ||||
-rw-r--r-- | pingora-proxy/src/proxy_h2.rs | 24 |
2 files changed, 28 insertions, 20 deletions
diff --git a/pingora-proxy/src/proxy_h1.rs b/pingora-proxy/src/proxy_h1.rs index 15ce038..544a74e 100644 --- a/pingora-proxy/src/proxy_h1.rs +++ b/pingora-proxy/src/proxy_h1.rs @@ -98,7 +98,7 @@ impl<SV> HttpProxy<SV> { ); match ret { - Ok((_first, _second)) => (true, true, None), + Ok((downstream_can_reuse, _upstream)) => (downstream_can_reuse, true, None), Err(e) => (false, false, Some(e)), } } @@ -204,13 +204,14 @@ impl<SV> HttpProxy<SV> { } // todo use this function to replace bidirection_1to2() + // returns whether this server (downstream) session can be reused async fn proxy_handle_downstream( &self, session: &mut Session, tx: mpsc::Sender<HttpTask>, mut rx: mpsc::Receiver<HttpTask>, ctx: &mut SV::CTX, - ) -> Result<()> + ) -> Result<bool> where SV: ProxyHttp + Send + Sync, SV::CTX: Send + Sync, @@ -416,16 +417,19 @@ impl<SV> HttpProxy<SV> { } } - match session.as_mut().finish_body().await { - Ok(_) => { - debug!("finished sending body to downstream"); - } - Err(e) => { - error!("Error finish sending body to downstream: {}", e); - // TODO: don't do downstream keepalive + let mut reuse_downstream = !downstream_state.is_errored(); + if reuse_downstream { + match session.as_mut().finish_body().await { + Ok(_) => { + debug!("finished sending body to downstream"); + } + Err(e) => { + error!("Error finish sending body to downstream: {}", e); + reuse_downstream = false; + } } } - Ok(()) + Ok(reuse_downstream) } async fn h1_response_filter( diff --git a/pingora-proxy/src/proxy_h2.rs b/pingora-proxy/src/proxy_h2.rs index f133c2f..53b2c14 100644 --- a/pingora-proxy/src/proxy_h2.rs +++ b/pingora-proxy/src/proxy_h2.rs @@ -176,7 +176,7 @@ impl<SV> HttpProxy<SV> { ); match ret { - Ok((_first, _second)) => (true, None), + Ok((downstream_can_reuse, _upstream)) => (downstream_can_reuse, None), Err(e) => (false, Some(e)), } } @@ -212,13 +212,14 @@ impl<SV> HttpProxy<SV> { (server_session_reuse, error) } + // returns whether server (downstream) session can be reused async fn bidirection_1to2( &self, session: &mut Session, client_body: &mut h2::SendStream<bytes::Bytes>, mut rx: mpsc::Receiver<HttpTask>, ctx: &mut SV::CTX, - ) -> Result<()> + ) -> Result<bool> where SV: ProxyHttp + Send + Sync, SV::CTX: Send + Sync, @@ -369,16 +370,19 @@ impl<SV> HttpProxy<SV> { } } - match session.as_mut().finish_body().await { - Ok(_) => { - debug!("finished sending body to downstream"); - } - Err(e) => { - error!("Error finish sending body to downstream: {}", e); - // TODO: don't do downstream keepalive + let mut reuse_downstream = !downstream_state.is_errored(); + if reuse_downstream { + match session.as_mut().finish_body().await { + Ok(_) => { + debug!("finished sending body to downstream"); + } + Err(e) => { + error!("Error finish sending body to downstream: {}", e); + reuse_downstream = false; + } } } - Ok(()) + Ok(reuse_downstream) } async fn h2_response_filter( |