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: ReceiveClosed
Reproduction
Run:
oha 'http://localhost:9000/api/requests/' -n 5000 -c 1000 -m POST --latency-correction -H 'Content-Type: application/json' -d '{"email":"test+999@mail.com"}'
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.
Summary
When running oha with high concurrency (e.g.
-n 5000 -c 1000) and especially with--latency-correctionenabled, worker tasks can panic with:Reproduction
Run:
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:
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
report_tx.send(...).unwrap();sites to handle channel closure gracefully, e.g.:ok()and silent exit when the receiver is gone, since there's nothing further the worker can do.send(...).unwrap()(other than in tests) and apply similar fix.Let me know if you need details or logs would be useful.