Skip to content

[triage:tooling-07-duplicated-worker-harness-http-dns] Worker/timing harness is duplicated between run_http_scenario and run_dns_scenario #151

Description

@ebursztein

Imported from Capsem triage report tooling-07-duplicated-worker-harness-http-dns.md.

  • Severity: low
  • Category: duplication
  • Area: capsem-bench
  • Location: crates/capsem-bench/src/main.rs:571-608 (HTTP) and 610-668 (DNS)
  • Confidence: verified

Summary

The two scenario runners share a byte-for-byte-identical work-splitting and timing skeleton: compute workers/per_worker/remainder, capture started, spawn one task per worker that loops count times, try_join_all, capture wall_time, flatten samples, and call summarize. Only the inner per-request call (and DNS's per-worker socket setup) differs. Any fix to the timing model — e.g. adding warmup or moving Instant::now() after spawn (see tooling-04) — must be applied in two places, and the DNS bind-failure inconsistency (tooling-03) exists precisely because the duplicated skeleton was copied without the per-request error-fanout that the HTTP path doesn't need.

Evidence

HTTP (lines 580-607):

let workers = concurrency.min(total_requests);
let per_worker = total_requests / workers;
let remainder = total_requests % workers;
let started = Instant::now();
let tasks = (0..workers).map(|idx| { let count = per_worker + usize::from(idx < remainder);
    tokio::spawn(async move { let mut out = Vec::with_capacity(count); for _ in 0..count { ... } out }) });
let joined = try_join_all(tasks).await...;
let wall_time = started.elapsed();
let samples = joined.into_iter().flatten().collect();
Ok(summarize(scenario, &samples, wall_time, total_requests, concurrency))

DNS (lines 618-667) is the same skeleton with let count = per_worker + usize::from(idx < remainder); and the identical started/try_join_all/wall_time/flatten/summarize tail.

Impact

Two-place maintenance for any timing/warmup change; the duplication already produced a divergence (DNS bind-failure path emits one sample instead of count, tooling-03) that a shared harness would have structurally prevented.

Suggested fix

Extract a generic run_scenario(workers, total_requests, concurrency, scenario, |worker_idx, count| async { Vec<RequestSample> }) that owns the split, timing, join, flatten, and summarize call. HTTP and DNS supply only the per-worker async closure. This also centralizes the fix point for warmup and post-spawn timing.

Triage

Confirmed from the local reviewed report in /Users/elie/git/capsem/tmp/bugs/tooling-07-duplicated-worker-harness-http-dns.md. Track implementation in the triage sprint; add regression coverage before fixing.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions