Panic: Unwrapping send on closed report channel causes ReceiveClosed in worker tasks under load
Summary
When running oha with high concurrency (e.g. -n 5000 -c 1000) and especially with --latency-correction enabled, worker tasks can panic with:
panic at src/client.rs:1254:49: called `Result::unwrap()` on an `Err` value: ReceiveClosedReproduction
Run:
oha 'http://localhost:9000/api/requests/' -n 5000 -c 1000 -m POST --latency-correction -H 'Content-Type: application/json' -d '{"email":"[email protected]"}'The panic is much more likely at high concurrency or when early shutdown occurs. It is triggered when the result receiver closes before all worker tasks finish.
Root cause
Code at src/client.rs:1245-1250:
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();
if is_cancel { break; }
}When the receiver is closed (for example, when test duration or parent task completes), further sends panic workers via .unwrap().
Impact
This is a race between result reporting and the receiver's lifetime. In normal or high-pressure use, fast termination of the receiver (parent) leaves workers panicking on .unwrap() if they race to send results after closed.
Possible solutions
- Change all
report_tx.send(...).unwrap();sites to handle channel closure gracefully, e.g.:if report_tx.send(res).is_err() { break; } - Prefer
ok()and silent exit when the receiver is gone, since there's nothing further the worker can do. - Audit all other worker/reporting codepaths for
send(...).unwrap()(other than in tests) and apply similar fix.
Let me know if you need details or logs would be useful.
Source: hatoo/oha