bench: assert --heavy-concurrency > 0 instead of silently clamping

Closes the cubic P2 finding on commit 22d76db: `Semaphore::new(concurrency.max(1))`
silently coerced --heavy-concurrency=0 to 1, so the JSON output reported
0 while execution actually used 1. Reported settings differed from
actual.

Adds an explicit `--heavy-concurrency > 0` check in `main()` (with a
helpful error message pointing to --heavy-batches=0 as the way to
disable heavy traffic) and a defensive `assert!()` inside
`drive_heavy_actor` so future callers can't pass 0 silently.

Verified: `bench_actor_isolation --heavy-concurrency 0` exits with
code 2 and the explanatory error message.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Ragnor Comerford 2026-05-08 19:23:02 +02:00
parent 3e6b2af4e9
commit 64f2b994f5
No known key found for this signature in database

View file

@ -158,7 +158,10 @@ async fn drive_heavy_actor(
) -> (usize, usize, usize) {
use tokio::sync::Semaphore;
let limiter = Arc::new(Semaphore::new(concurrency.max(1)));
// Asserted at startup in `main()`; check again here for defense in
// depth so a future caller can't pass 0 silently.
assert!(concurrency > 0, "drive_heavy_actor concurrency must be > 0");
let limiter = Arc::new(Semaphore::new(concurrency));
let mut handles = Vec::with_capacity(batches);
for b in 0..batches {
let app = app.clone();
@ -251,6 +254,13 @@ async fn main() {
eprintln!("--light-actors, --light-ops-per-actor, --heavy-batches must all be > 0");
std::process::exit(2);
}
if args.heavy_concurrency == 0 {
eprintln!(
"--heavy-concurrency must be > 0 (zero would prevent the heavy actor from \
ever firing a batch; if you want to disable heavy traffic, set --heavy-batches=0)"
);
std::process::exit(2);
}
let temp = tempfile::tempdir().expect("tempdir");
let repo = temp.path().join("bench.omni");