Skip to content

test(wasm): pace the read case's publisher by its reader - #5827

Merged
kixelated merged 2 commits into
mainfrom
quest/m1/test-flakes-2/wasm-ietf-read
Oct 17, 2026
Merged

kixelated merged 2 commits into
mainfrom
quest/m1/test-flakes-2/wasm-ietf-read

Conversation

@kixelated

@kixelated kixelated commented Oct 17, 2026 •

Copy link
Copy Markdown
Collaborator

Completes /quest/m1/test-flakes-2/wasm-ietf-read.md (reopened after #5650).

Cause

The fixture published a 128 KiB group every 50 ms (2.6 MB/s). The wasm subscription uses the default Latency::REAL_TIME budget (max_delay 0; the binding hard-codes subscribe(None)). Under that budget, a reader that parks for more bytes after a newer group has landed gets old (model/group.rs poll_expired_if_blocked, model/track.rs superseded). On a loaded runner the browser and relay deliver a group slower than 50 ms. With TRACE on, the relay took ~150 ms to forward one group, so every group is superseded mid-read and none arrives whole.

This isn't IETF-specific:

  • CI history: setup (lite-02) failed the same way on 2026-09-29 (run 36504066809, read 1 whole groups in 8 attempts). Its log has the same shape: group 0, an 890 ms gap, then groups 1-7 within 6 ms.
  • Local reproduction (suite pinned to 2 cores with busy loops competing): old skips on all three flavours.
  • Why a burst kills groups: the stall-then-burst is delivery lag on the runner. When it releases, the newer groups' headers land while older groups are still arriving, so the older groups are retired. That is correct real-time behaviour: a group that had fully arrived is always drained, and only a group the reader is still waiting on is dropped.

The earlier unsupported signature (2026-10-09 to 10-12) was a relay REQUEST_ERROR on SUBSCRIBE from TRACK_STATUS. It last appeared before #5409 and #5468 merged and hasn't recurred.

Change

  • The publisher appends one group once the track has demand, then one more each time the reader calls advance(). No group is ever superseded while it is being read.
  • expectGroups reads exactly count groups and requires consecutive sequences. Any skip or short group fails. This restores the bound, stricter than count * 4: the cause leaves no legal skip.
  • Removed isOld, GROUP_INTERVAL_MS, and sleep. The README case description now matches what the case does.

Public API: none. Wire: none.

Evidence

Interleaved A/B on a loaded shared host (load average ~36 on 32 cores), Nix Chromium 155, the suite pinned with taskset alongside competing busy loops. A is main with the old count * 4 bound restored; B is this PR.

setup A fails B fails
2 cores, 6 busy loops 1/6 (setup: read 0 whole groups in 8 attempts) 0/6
1 core, 3 busy loops 3/6 (lite, ietf, and setup each failed) 0/6

just check passes.

Decision

Settled by the maintainer (2026-10-17): land option 1, the reader-paced fixture. The alternatives were a latency-budget parameter on @moq/wasm subscribe (public API, and any finite budget can still be outrun) or asserting only what REAL_TIME promises (drops "whole groups").

Follow-ups

  • The 500-900 ms delivery stalls themselves (loopback WebTransport on CI, where the relay warns its UDP send buffer was granted 208 KiB) are not explained here. Relay QUIC stats in the WASM job's failure artifact would show whether it's loss recovery.
  • On a NixOS host, Playwright's bundled Chromium can't load libglib. An env override for the browser's executablePath in test/wasm/driver.ts would let local runs reproduce (test: let real-time wasm reads skip freely #5650 couldn't).

🤖 Generated with Claude Code

(Written by Claude Opus 5.5)

@kixelated

Copy link
Copy Markdown
Collaborator Author

Outcome: cause found. The REAL_TIME (zero) budget drops a group superseded mid-read, and a 50 ms timer outruns a loaded runner, on lite-02 as well as IETF. Fixed by pacing the fixture's publisher by the reader. The bound is back and stricter: exactly two consecutive whole groups. Interleaved A/B on a loaded host: the old bound failed 4 of 12 runs, this PR 0 of 12. It's a draft for one maintainer decision (reader pacing vs. a wasm latency-budget API vs. a weaker assertion); see the description.

(Written by Claude Opus 5.5)

kixelated and others added 2 commits October 17, 2026 07:42
The fixture published a 128 KiB group every 50 ms into a subscription with
the default REAL_TIME budget, which gives up on a group still arriving once
a newer one lands. On a loaded runner the browser and relay deliver a group
slower than that, so every group was superseded mid-read and the case read
none whole. This hit lite-02 as well as IETF; the stall-then-burst in the
IETF logs is the same delivery lag, not an IETF code path.

The publisher now appends the next group only when the reader asks, so the
case reads exactly two consecutive whole groups again and any skip fails.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@kixelated
kixelated force-pushed the quest/m1/test-flakes-2/wasm-ietf-read branch from dd58a27 to b1aa995 Compare October 17, 2026 14:43
@kixelated
kixelated marked this pull request as ready for review October 17, 2026 14:43
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 17, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-17T14:45:43.876428Z b1aa995 Draft marked ready
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@coderabbitai

coderabbitai Bot commented Oct 17, 2026

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 19 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used all 4 included reviews currently available.

Learn how review limits work.

Review configuration:

⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: edc36617-6685-4444-8ac0-e1052c5df623
📥 Commits

Reviewing files that changed from the base of the PR and between e93391d and b1aa995.

📒 Files selected for processing: 4
  • quest/m1/test-flakes-2/README.md
  • quest/m1/test-flakes-2/wasm-ietf-read.md
  • test/wasm/README.md
  • test/wasm/src/main.ts
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@kixelated

Copy link
Copy Markdown
Collaborator Author

Merge summary: rebased on main (one conflict in the epic README's Required list; resolved by keeping main's entries and removing this quest's). The decision is settled: the maintainer chose the reader-paced fixture (option 1). CI is green, including the WASM job. Codex reviewed b1aa995 with no findings; CodeRabbit was rate-limited and didn't review. Two follow-ups stay open, both listed in the description: the unexplained 500-900 ms CI delivery stalls, and a Chromium executable override for NixOS hosts.

(Written by Claude Opus 5.5)

@kixelated
kixelated added this pull request to the merge queue Oct 17, 2026
Merged via the queue into main with commit 9cd2ce8 Oct 17, 2026
11 checks passed
@kixelated
kixelated deleted the quest/m1/test-flakes-2/wasm-ietf-read branch October 17, 2026 15:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant