aboutsummaryrefslogtreecommitdiffhomepage
path: root/pingora-proxy
diff options
context:
space:
mode:
authorEdward Wang <[email protected]>2024-10-04 00:24:49 -0700
committerYuchen Wu <[email protected]>2024-10-11 16:52:23 -0700
commit894ca2dd64526c49a9adc43aa45a0a0f32743987 (patch)
treeee3ad689cbe747dadcc05fc4f1d8735226d9d553 /pingora-proxy
parent792d5fd3c14c1cd588b155ddf09c09a4c125a26b (diff)
downloadpingora-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.rs24
-rw-r--r--pingora-proxy/src/proxy_h2.rs24
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(