Open taikulawo opened 1 day ago
pingora send body to proxy_handle_upstream
even if body is empty, which send upstream_end_of_body == true
, causing proxy_handle_upstream
exit early
// retry, send buffer if it exists or body empty
// false || true
if buffer.is_some() || session.as_mut().is_body_empty() {
let send_permit = tx
.reserve()
.await
.or_err(InternalError, "reserving body pipe")?;
let end_of_body = self.send_body_to_pipe(
session,
buffer,
downstream_state.is_done(),
send_permit,
ctx,
)
.await?;
// ++++ we should finish body if return value is true
downstream_state.maybe_finished(end_of_body);
}
// retry, send buffer if it exists or body empty // false || true if buffer.is_some() || session.as_mut().is_body_empty() { let send_permit = tx .reserve() .await .or_err(InternalError, "reserving body pipe")?; let end_of_body = self.send_body_to_pipe( session, buffer, downstream_state.is_done(), send_permit, ctx, ) .await?; // ++++ should we finish body if return value is true ? downstream_state.maybe_finished(end_of_body); }
Describe the bug
We receive many
waiting for permit
log, CPU go to 100%Pingora info
We forked pingora code into our own codebase
Pingora version: release number of commit hash Rust version: i.e. cargo 1.82.0 (8f40fc59f 2024-08-21) Operating system version: Centos 8
Steps to reproduce
first, pingora pipe upstream/downstream, it's OK.
But if
proxy_handle_upstream
exit early thanproxy_handle_downstream
,rx
will be droped.In
proxy_handle_downstream
, we get permit first.But since rx already been droped. send_permit will be
Closed
, notFull
send_permit.is_ok()
will already be Error. It will NEVER been polled again!tx.reserve() will always return Error since it be closed,
finally, forward deadloop
Expected results
works corrently
Observed results
Our server deadloop
Additional context