Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 48 additions & 26 deletions src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1064,10 +1064,19 @@ async fn work_http2_once(
if let Some(start_latency_correction) = start_latency_correction {
set_start_latency_correction(&mut res, start_latency_correction);
}
report_tx.send(res).unwrap();
send_report(report_tx, res);
(is_cancel, is_reconnect)
}

/// Reports a completed request unless reporting has already stopped.
///
/// The receiver can be dropped while workers are winding down after a deadline
/// or cancellation. At that point the result cannot be consumed, and a worker
/// must not panic merely because it can no longer report it.
pub(crate) fn send_report<T>(report_tx: &kanal::Sender<T>, result: T) {
let _ = report_tx.send(result);
}

pub(crate) fn set_connection_time<E>(
res: &mut Result<RequestResult, E>,
connection_time: ConnectionTime,
Expand Down Expand Up @@ -1209,7 +1218,7 @@ pub async fn work(
}
Err(err) => {
if counter.fetch_add(1, Ordering::Relaxed) < n_tasks {
report_tx.send(Err(err)).unwrap();
send_report(&report_tx, Err(err));
} else {
return;
}
Expand All @@ -1234,7 +1243,7 @@ pub async fn work(
while counter.fetch_add(1, Ordering::Relaxed) < n_tasks {
let res = client.work_http1(&mut client_state).await;
let is_cancel = is_cancel_error(&res);
report_tx.send(res).unwrap();
send_report(&report_tx, res);
if is_cancel {
break;
}
Expand Down Expand Up @@ -1375,7 +1384,7 @@ pub async fn work_with_qps(
Err(err) => {
// Consume a task
if let Ok(()) = rx.recv().await {
report_tx.send(Err(err)).unwrap();
send_report(&report_tx, Err(err));
} else {
return;
}
Expand All @@ -1402,7 +1411,7 @@ pub async fn work_with_qps(
while let Ok(()) = rx.recv().await {
let res = client.work_http1(&mut client_state).await;
let is_cancel = is_cancel_error(&res);
report_tx.send(res).unwrap();
send_report(&report_tx, res);
if is_cancel {
break;
}
Expand Down Expand Up @@ -1549,7 +1558,7 @@ pub async fn work_with_qps_latency_correction(
Err(err) => {
// Consume a task
if rx.recv().await.is_ok() {
report_tx.send(Err(err)).unwrap();
send_report(&report_tx, Err(err));
} else {
return;
}
Expand Down Expand Up @@ -1577,7 +1586,7 @@ pub async fn work_with_qps_latency_correction(
let mut res = client.work_http1(&mut client_state).await;
set_start_latency_correction(&mut res, start);
let is_cancel = is_cancel_error(&res);
report_tx.send(res).unwrap();
send_report(&report_tx, res);
if is_cancel {
break;
}
Expand Down Expand Up @@ -1686,7 +1695,7 @@ pub async fn work_until(
}
}
_ = s.acquire() => {
report_tx.send(Err(ClientError::Deadline)).unwrap();
send_report(&report_tx, Err(ClientError::Deadline));
connection_gone = true;
}
}
Expand All @@ -1697,7 +1706,7 @@ pub async fn work_until(
}

Err(err) => {
report_tx.send(Err(err)).unwrap();
send_report(&report_tx, Err(err));
if s.is_closed() {
break;
}
Expand Down Expand Up @@ -1728,7 +1737,7 @@ pub async fn work_until(
loop {
let res = client.work_http1(&mut client_state).await;
let is_cancel = is_cancel_error(&res);
report_tx.send(res).unwrap();
send_report(&report_tx, res);
if is_cancel || is_end.load(Relaxed) {
break;
}
Expand All @@ -1750,7 +1759,7 @@ pub async fn work_until(
if let Err(e) = f.await
&& e.is_cancelled()
{
report_tx.send(Err(ClientError::Deadline)).unwrap();
send_report(&report_tx, Err(ClientError::Deadline));
}
}
}
Expand Down Expand Up @@ -1890,7 +1899,7 @@ pub async fn work_until_with_qps(
}
}
_ = s.acquire() => {
report_tx.send(Err(ClientError::Deadline)).unwrap();
send_report(&report_tx, Err(ClientError::Deadline));
connection_gone = true;
}
}
Expand All @@ -1902,7 +1911,7 @@ pub async fn work_until_with_qps(
Err(err) => {
// Consume a task
if rx.recv().await.is_ok() {
report_tx.send(Err(err)).unwrap();
send_report(&report_tx, Err(err));
} else {
return;
}
Expand Down Expand Up @@ -1938,7 +1947,7 @@ pub async fn work_until_with_qps(
while let Ok(()) = rx.recv().await {
let res = client.work_http1(&mut client_state).await;
let is_cancel = is_cancel_error(&res);
report_tx.send(res).unwrap();
send_report(&report_tx, res);
if is_cancel || is_end.load(Relaxed) {
break;
}
Expand All @@ -1960,7 +1969,7 @@ pub async fn work_until_with_qps(
if let Err(e) = f.await
&& e.is_cancelled()
{
report_tx.send(Err(ClientError::Deadline)).unwrap();
send_report(&report_tx, Err(ClientError::Deadline));
}
}
}
Expand Down Expand Up @@ -2098,7 +2107,7 @@ pub async fn work_until_with_qps_latency_correction(
}
}
_ = s.acquire() => {
report_tx.send(Err(ClientError::Deadline)).unwrap();
send_report(&report_tx, Err(ClientError::Deadline));
connection_gone = true;
}
}
Expand All @@ -2110,7 +2119,7 @@ pub async fn work_until_with_qps_latency_correction(

Err(err) => {
if rx.recv().await.is_ok() {
report_tx.send(Err(err)).unwrap();
send_report(&report_tx, Err(err));
} else {
return;
}
Expand Down Expand Up @@ -2147,7 +2156,7 @@ pub async fn work_until_with_qps_latency_correction(
let mut res = client.work_http1(&mut client_state).await;
set_start_latency_correction(&mut res, start);
let is_cancel = is_cancel_error(&res);
report_tx.send(res).unwrap();
send_report(&report_tx, res);
if is_cancel || is_end.load(Relaxed) {
break;
}
Expand All @@ -2169,7 +2178,7 @@ pub async fn work_until_with_qps_latency_correction(
if let Err(e) = f.await
&& e.is_cancelled()
{
report_tx.send(Err(ClientError::Deadline)).unwrap();
send_report(&report_tx, Err(ClientError::Deadline));
}
}
}
Expand All @@ -2195,7 +2204,7 @@ pub mod fast {
result_data::ResultData,
};

use super::Client;
use super::{Client, send_report};

/// Run n tasks by m workers
pub async fn work(
Expand Down Expand Up @@ -2321,7 +2330,7 @@ pub mod fast {
}
};

report_tx.send(result_data).unwrap();
send_report(&report_tx, result_data);
is_cancel
})
})
Expand Down Expand Up @@ -2357,7 +2366,7 @@ pub mod fast {
}
}
if has_err {
report_tx.send(result_data_err).unwrap();
send_report(&report_tx, result_data_err);
}
}));
}
Expand Down Expand Up @@ -2403,7 +2412,7 @@ pub mod fast {
}
} => {}
}
report_tx.send(result_data).unwrap();
send_report(&report_tx, result_data);
}));
}
rt.block_on(local);
Expand Down Expand Up @@ -2540,7 +2549,7 @@ pub mod fast {
}
};

report_tx.send(result_data).unwrap();
send_report(&report_tx, result_data);
is_cancel
})
})
Expand Down Expand Up @@ -2575,7 +2584,7 @@ pub mod fast {
}
}
if has_err {
report_tx.send(result_data_err).unwrap();
send_report(&report_tx, result_data_err);
}
}));
}
Expand Down Expand Up @@ -2626,7 +2635,7 @@ pub mod fast {
result_data.push(Err(ClientError::Deadline));
}
}
report_tx.send(result_data).unwrap();
send_report(&report_tx, result_data);
}));
}
rt.block_on(local);
Expand All @@ -2653,3 +2662,16 @@ pub mod fast {
});
}
}

#[cfg(test)]
mod tests {
use super::send_report;

#[test]
fn send_report_ignores_a_closed_receiver() {
let (report_tx, report_rx) = kanal::unbounded();
drop(report_rx);

send_report(&report_tx, ());
}
}
14 changes: 7 additions & 7 deletions src/client_h3.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ pub enum Http3Error {

use crate::client::QueryLimit;
use crate::client::{
Client, ClientError, ConnectionTime, RequestResult, Stream, is_cancel_error,
Client, ClientError, ConnectionTime, RequestResult, Stream, is_cancel_error, send_report,
set_connection_time, set_start_latency_correction,
};
use crate::pcg64si::Pcg64Si;
Expand Down Expand Up @@ -386,7 +386,7 @@ async fn create_and_load_up_single_connection_http3(
}
}
_ = s.acquire() => {
report_tx.send(Err(ClientError::Deadline)).unwrap();
send_report(&report_tx, Err(ClientError::Deadline));
connection_gone = true;
}
}
Expand All @@ -404,12 +404,12 @@ async fn create_and_load_up_single_connection_http3(
} else if let Some(rx) = &rx {
// Consume a task
if rx.recv().await.is_ok() {
report_tx.send(Err(err)).unwrap();
send_report(&report_tx, Err(err));
} else {
return;
}
} else {
report_tx.send(Err(err)).unwrap();
send_report(&report_tx, Err(err));
}
}
}
Expand Down Expand Up @@ -475,7 +475,7 @@ pub(crate) async fn work_http3_once(
if let Some(start_latency_correction) = start_latency_correction {
set_start_latency_correction(&mut res, start_latency_correction);
}
report_tx.send(res).unwrap();
send_report(report_tx, res);
(is_cancel, is_reconnect)
}

Expand Down Expand Up @@ -568,7 +568,7 @@ pub(crate) fn http3_connection_fast_work_until(
}
};

report_tx.send(result_data).unwrap();
send_report(&report_tx, result_data);
is_cancel
})
})
Expand Down Expand Up @@ -608,7 +608,7 @@ pub(crate) fn http3_connection_fast_work_until(
}
}
if has_err {
report_tx.send(result_data_err).unwrap();
send_report(&report_tx, result_data_err);
}
}));
}
Expand Down