Skip to content

fix(net): an IETF TRACK_STATUS refused as NOT_SUPPORTED falls back to SUBSCRIBE - #5409

Merged
kixelated merged 1 commit into
mainfrom
fix/ietf-track-status-unsupported
Oct 13, 2026
Merged

kixelated merged 1 commit into
mainfrom
fix/ietf-track-status-unsupported

Conversation

@kixelated

@kixelated kixelated commented Oct 13, 2026 •

Copy link
Copy Markdown
Collaborator

Problem

The WASM job intermittently fails ietf cases with unsupported (error code 3): ietf: reads a published broadcast and ietf: free() cancels a pending read. It has flaked on PR branches since 2026-10-09 (runs 37992181995, 38055854662, 38088705982, 38109989381, 38110085471, 38179687337, 38184448714, 38195885210, 38344051897, 38352106340), always passing on rerun.

Root cause, from the CI relay logs and a forced local repro:

  1. The relay's IETF publisher handles a downstream SUBSCRIBE by calling broadcast.track(name) and then track.subscribe(..).
  2. track() hands the origin's front a new track. If the front's driver runs Action::Query before the subscription registers, it sees no subscription and only query()s the source copy.
  3. The upstream IETF subscriber treats demand with no subscription as fetch-only and sends TRACK_STATUS, which feat(moq-net): IETF fetch-only demand uses TRACK_STATUS, and properties are asked once #4974 introduced.
  4. The fixture publisher is @moq/net, which refuses every TRACK_STATUS with NOT_SUPPORTED. The subscriber rejected the track with Error::Unsupported, so the front aborted it and the downstream SUBSCRIBE was answered NOT_SUPPORTED, "unsupported".

In the failing CI relay logs, the relay logs subscribe started for the downstream SUBSCRIBE but never sends an upstream SUBSCRIBE. Adding 50 cooperative yields between track() and subscribe() in the relay publisher made just test wasm's ietf relay fail 3/3 iterations with the same two cases. The debug logs showed track status refused err=unsupported followed by aborting track name=data err=unsupported.

#5385 is not involved. The failure predates it, and the PR #5244 failure ran on a merge base without it.

Approach

When the publisher refuses TRACK_STATUS with NOT_SUPPORTED, the IETF subscriber now hands the request back and SUBSCRIBEs instead of rejecting the track. NOT_SUPPORTED refuses the method, not the track. Draft-17 already learns tracks this way. Other refusals (not found, unauthorized, ...) still reject the request.

track_status now returns the Target to continue with instead of an Idle copy.

Impact

  • No public API change.
  • Wire: against a publisher that refuses TRACK_STATUS as NOT_SUPPORTED, a Rust subscriber now follows that refusal with a SUBSCRIBE. Before, the track failed.

Tests

  • an_unsupported_track_status_subscribes_instead (drafts 18, 19, 22) fails without the fix: the query resolves Unsupported.
  • With the forced window, the WASM ietf relay passed 20/20 iterations, taking the fallback every time.
  • just check passes.

Alternatives

  • Make the publisher's track lookup and subscribe atomic, so a reader's request never looks fetch-only. That would be a model API change, and fetch-only demand against a publisher without TRACK_STATUS would still fail.
  • Implement TRACK_STATUS in @moq/net. Worth doing for interop, but a Rust subscriber should still survive a peer that refuses it.

Follow-ups

  • The race still costs a TRACK_STATUS round trip before the SUBSCRIBE on a reader's first request, even against publishers that support it. Worth a quest if that latency matters.

(Written by Claude Opus 5.5)

🤖 Generated with Claude Code


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need.

… SUBSCRIBE

The origin queries a new track before its first reader's subscription
lands, so the IETF subscriber can send TRACK_STATUS for a reader's
request. A publisher without TRACK_STATUS (the JavaScript one) answers
NOT_SUPPORTED, which refused the track itself, and the downstream
SUBSCRIBE failed with "unsupported". That refusal is about the method,
so learn the track from SUBSCRIBE instead.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@kixelated
kixelated marked this pull request as ready for review October 13, 2026 07:47
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 13, 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-13T07:50:18.900696Z 30fb5cc 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.

@kixelated kixelated left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Automated review by review (OpenAI)

Reviewed 30fb5cc against base 0177c46.

No actionable bugs found in the two-file patch and relevant request lifecycle/version handling. The targeted fallback looks sound: subscriber.rs:2944–2947 returns the original pending request only for NOT_SUPPORTED, so the existing SUBSCRIBE path owns acceptance, cancellation, alias registration, and cleanup. Successful TRACK_STATUS still follows the fetch-only linger path; other refusals still reject.

Reusing Target is a simpler, localized fix than changing the track model. The new regression checks query acceptance and TRACK_STATUS→SUBSCRIBE ordering for drafts 18/19/22; it does not independently establish live data delivery or cancellation coverage.

Static review only; I did not run tests or reproduce the WASM race.

@coderabbitai

coderabbitai Bot commented Oct 13, 2026

Copy link
Copy Markdown
Contributor

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 466229fb-2dcd-45cd-82d7-45d2978c2320
📥 Commits

Reviewing files that changed from the base of the PR and between 0177c46 and 30fb5cc.

📒 Files selected for processing (2)
  • doc/concept/standard.md
  • rs/moq-net/src/ietf/subscriber.rs

Included review availability: This review used your included allowance. Your plan provides up to 4 included reviews per hour; 0 remain after this review.

Walkthrough

When TRACK_STATUS returns NOT_SUPPORTED, track_status returns the original request target and the fetch-only setup proceeds with SUBSCRIBE. When TRACK_STATUS succeeds, the reader resumes from the learned idle track. A new test verifies the unsupported-status fallback for drafts 18, 19, and 22. The concept documentation now describes this fallback.

Priority: ➖ Normal

Merge Risk: ⚪ Minimal · up to 30fb5

The change appears ready to merge after normal checks; no unresolved issue is identified.

Pre-merge checks · Passed 4 · Failed 1

Failed Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 71.43% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 7 functions across 1 files. (1 skipped: 1… Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed Passed checks (4 passed)
Check name Status Explanation
Title check Passed The title clearly and concisely describes the main change: falling back to SUBSCRIBE when TRACK_STATUS returns NOT_SUPPORTED.
Description check Passed The description directly explains the intermittent failure, root cause, implementation approach, wire impact, tests, and alternatives. It is fully related to the changeset.
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Full details: Docstring Coverage

Explanation

Docstring coverage is 71.43% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 7 functions across 1 files. (1 skipped: 1 unsupported.)

  • Fix all pre-merge checks with AI
✨ Finishing Touches
✨ Simplify code
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Warning

Some tools did not complete. Review the errors below.

🔧 Clippy (1.98.1)

Clippy execution timed out

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 for 30fb5cc:

  • CI: Check, Test, WASM, Android, Windows, and macOS all pass.
  • Reviews: Codex gave a thumbs-up on this head. CodeRabbit and the OpenAI review found nothing actionable.
  • Interop: just test interop --all passes locally on this head. The interop workflow doesn't run for these paths.
  • Decisions: none needed. The fallback only covers NOT_SUPPORTED, and every other refusal still rejects the track.

Follow-ups, not part of this PR:

  • Implement TRACK_STATUS in @moq/net, so fetch-only readers learn tracks without falling back to SUBSCRIBE.
  • A reader's first request still races the origin's query, which costs one TRACK_STATUS round trip before the SUBSCRIBE.

Enabling auto-merge.

(Written by Claude Opus 5.5)

@kixelated
kixelated added this pull request to the merge queue Oct 13, 2026
Merged via the queue into main with commit 7a32f84 Oct 13, 2026
7 checks passed
@kixelated
kixelated deleted the fix/ietf-track-status-unsupported branch October 13, 2026 16:16
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