Skip to content

id(world_net): inbound_refusal_backpressures test is flaky — intermittent "a pre-auth refusal sheds the stream" #5195

Closed

Description

@dezren39

Observed 2026-11-03 on the laptop (amd-6) while verifying the #5020/#5021/#5128/#5132 fixes — unrelated to those changes (different subsystem; none of them touch world_net), filed so it exists as a tracked problem:

world_net::tests::inbound_refusal_backpressures_authorized_streams_but_sheds_preauth panics intermittently at src/world_net.rs:2171:

a pre-auth refusal sheds the stream

Evidence, all on origin/main 80b06f8:

  • Full cargo test -p id run under parallel load: lib target 2038 passed / 1 failed — this test.
  • In isolation (cargo test -p id --lib -- inbound_refusal_backpressures), three consecutive runs: pass, fail, pass.
  • Same day, a full --no-fail-fast run (43 targets, 2501 passed / 0 failed) and the nix build .#id-web sandbox check phase (3294 passed / 0 failed) both had it green.

So it is timing/load-sensitive rather than broken. It still matters: .#id-web runs this suite in its Nix check phase (doCheck=true), so an unlucky run can intermittently redden the build and block the laptop fleet switch with a failure that is not a regression.

Acceptance: the test passes reliably under load (e.g. repeated full-lib runs on a busy machine), by fixing the synchronization/timing assumption in the test (or the backpressure behavior, if the flake exposes a real race).

Acceptance criteria

  • world_net::tests::inbound_refusal_backpressures_authorized_streams_but_sheds_preauth passes reliably under load: repeated full cargo test -p id --lib runs on a busy machine (10+ consecutive) with zero failures of this test.
  • The fix addresses the synchronization/timing assumption in the test — or, if the flake exposes a real backpressure race, the behavior in src/world_net.rs — with the root cause named in the closing comment.
  • The nix build .#id-web check phase stays green.

Activity

  1. added
    kind/bugSomething isn't working (prefixed form of the classic bug label)
    priority/highImportant and time-sensitive
    effort/sSmall: expected under 2 hours of work
    app/idPackage/app: id (pkgs/ or apps/ in this repo)
    meta/enrichedIntake review done: acceptance criteria, links, and normalized labels added
    on Nov 3, 2026
  2. dezren39 commented on Nov 3, 2026

    @dezren39
    MemberAuthor

    Intake review

    Related: Filed while verifying the #5020/#5021/#5128/#5132 fixes (different subsystem). CI-runner context: #5194.

    Notes: Flaky-test filing with strong evidence: pass/fail/pass in isolation on main 80b06f8, green in two other full runs the same day. No merged PR touches world_net backpressure in a way that resolves this (merged-PR search this run: none). Risks: timing flakes invite timeout-bump non-fixes; the acceptance bar (10 consecutive full-lib runs under load) is set to reject those. Suggested approach: reproduce under load first, inspect the await/poll assumptions around src/world_net.rs:2171, prefer a deterministic synchronization fix over sleeps.

    — fleet monitor intake (protocol §5), 2026-11-03. Verified still live this run: no merged PR resolves this issue.

  3. added 2 commits that reference this issue on Nov 4, 2026
  4. dezren39 commented on Nov 4, 2026

    @dezren39
    MemberAuthor

    Fixed in #5215 (merge 03755976447ef02030efc66f584b67fc9befa714 on main).

    Root cause

    A timing assumption in the test, not a backpressure race. The test configured frames_per_sec: 1_000, frame_burst: 1 (and the same for bytes). The evaluator buckets (src/abuse.rs) count milli-tokens: capacity 1_000, refill 1_000 milli-tokens per millisecond. After the first pre-auth charge drains the bucket, one full token is back after 1 ms of wall time — so the shed assertion ("second pre-auth charge is refused") only holds if the test thread happens to run the second charge within that same ~1 ms window. Any scheduling stall ≥ 1 ms between the two charges (parallel full-suite load, sandbox CPU throttling) admits the second charge, charge_inbound_frame returns true, and the assert fires. Every lib step (refill, refusal, retry clamp to [1 s, 60 s]) behaves as designed throughout.

    Fix (test-only, pkgs/id/src/world_net.rs)

    • Rates drop to 1 token/sec, burst still 1: a drained bucket stays empty ~1 s, giving the shed leg ~1000x margin over scheduler jitter. The authorized leg is unchanged in shape and duration (~1 s via the existing retry floor, inside its 3 s bound).
    • The two previously bare first-charge awaits are wrapped in 5 s timeouts with loud expects, so every await in the test is bounded — a wedged charge now fails loudly in seconds instead of stalling a suite (which matters in the nix check phase, where the laptop sets max-silent-time = 0 and nothing reaps a silent build).

    Verification

    • Post-fix: 101/101 runs of the named test pass on the loaded laptop (1 single, 40 under 32-way CPU saturation, 60 across 6 parallel streams), each ~1.0 s. Family context on the fixed binary: world_net::tests 22/22, abuse::tests 12/12, frames::tests 5/5. Edited region rustfmt-clean.
    • Pre-fix, the unmodified test ran 450 times with 0 failures (240 isolated/parallel, 60 pinned to one CPU under busy hogs, 150 under CPU saturation) — the flake needs the full-suite context the arithmetic predicts; the failures recorded at filing plus the 1 ms window are the proof of mechanism.
    • Caveat on the "10 consecutive full-lib runs" bar: full cargo test -p id --lib runs on the host are currently blocked by an unrelated, separately filed bug — every test that builds the clap command tree stack-overflows and aborts the binary on this host (id(cli): module_trust_keys test stack-overflows on host runs (unbounded recursion), aborts full-lib suite #5216; the same tests pass in the sandbox). The named-test and family verifications above stand in for it. A nix build .#id-web check-phase build of the fixed tree was started from the fix worktree and is in flight at closing time; the identical test target is compile- and run-verified on the host.

    Hang verdict (the 52-minute switch incident)

    Not this test, on the evidence: 450 pre-fix runs with no hang, and a code audit showing every wait in its path is a tokio sleep of a refusal delay clamped to at most 60 s, with its substantive charges wrapped in 500 ms / 3 s timeouts (and now its first charges bounded too). A test binary sitting single-threaded at 0 CPU for 52 minutes is far more consistent with an unbounded network await elsewhere in a check-phase suite (the id lib binary carries live-iroh tests whose connects/receives have no outer timeout) than with this bounded test. The switch hang remains formally unattributed — it is not evidence against this test, and this fix does not claim to have repaired it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    app/idPackage/app: id (pkgs/ or apps/ in this repo)effort/sSmall: expected under 2 hours of workkind/bugSomething isn't working (prefixed form of the classic bug label)meta/enrichedIntake review done: acceptance criteria, links, and normalized labels addedpriority/highImportant and time-sensitivestatus/needs-triageNot yet triaged; needs a first look

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions