Skip to content

fix(net): skip a stale warm cache on an IETF rejoin - #4150

Merged
kixelated merged 1 commit into
mainfrom
claude/ietf-warm-stale
Sep 25, 2026
Merged

kixelated merged 1 commit into
mainfrom
claude/ietf-warm-stale

Conversation

@kixelated

Copy link
Copy Markdown
Collaborator

Problem

#4104 stopped a relay from handing a returning reader a parked track's stale warm cache, but only for lite-06+ upstreams. On an IETF upstream (every draft), a rejoining reader still got the newest cached group before live, the same as on main: broadcast_rejoin_skips_a_stale_warm_cache failed on IETF with "served the stale cache first: group 3".

After #4104, live readers wait on the warm cache until the next upstream copy declares where its feed starts, and skip the cache if that start is past the cache's newest group. The IETF subscriber never declared a start, so the cache was always released.

Approach

An IETF re-subscription is always a live join. The request is only accepted at SUBSCRIBE_OK, so the SUBSCRIBE goes out before any reader is attached and carries no start. A live join delivers nothing below the group SUBSCRIBE_OK names as Largest: the draft-20 fill and the pre-20 joining FETCH both begin at that group. So the IETF subscriber now declares that group as the copy's start, atomically with accepting it. A warm cache whose newest group is older is skipped. One the upstream is still on (a quiet catalog, or an open JSON log) is kept. With no Largest (no content), no start is declared and the cache is kept.

Tests:

Impact

  • Public API: none.
  • Wire: none. It reads the existing SUBSCRIBE_OK Largest Location.
  • Behavior: an IETF live join now records a start floor. Besides the warm cache hold, the only other reader of it is poll_peek_group, which treats a missing group below the floor as skipped rather than pending. That is true for a live join.

Not covered

Pre-06 lite upstreams still serve one stale group on rejoin (same as main). Their SUBSCRIBE_OK carries no Largest, so the only signal would be the first served group. That would make a returning reader wait on an empty upstream track. Say if it's worth doing.

🤖 Generated with Claude Code

(Written by Claude Opus 5.5)

An IETF live join delivers nothing below the group its SUBSCRIBE_OK names as
Largest, so declare that as the copy's start. A parked track's warm cache
waiting on the copy then sees the upstream moved past it and live readers
skip it, as they already do on lite-06+.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Sep 25, 2026

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

Next included review available in 20 minutes.

Check out review usage here.

View limit details

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

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

Learn how review limits work.

Review configuration:

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Advanced

Run ID: 78364b43-a4c6-4ef4-ae0b-8cd8a6482410

📥 Commits

Reviewing files that changed from the base of the PR and between 3b4ad5b and 529184d.

📒 Files selected for processing (2)
  • rs/moq-net/src/ietf/subscriber.rs
  • rs/moq-tokio/tests/broadcast.rs

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.

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 25, 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-09-25T14:14:14.279320Z 529184d PR opened
ℹ️ 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

Copy link
Copy Markdown
Collaborator Author

MERGE

Positive improvement. #4104 already taught live readers to wait on the warm cache until the upstream copy declares a start floor, then skip it when that floor is past the cache. IETF never declared one, so the cache always released and broadcast_rejoin_skips_a_stale_warm_cache failed with “served the stale cache first.” Wiring SUBSCRIBE_OK’s Largest into that same floor closes the gap for every IETF draft without a new wire signal.

Worth the complexity. Eleven lines in ietf/subscriber.rs, same resolving_start → accept → start_at shape lite-06+ already uses when SUBSCRIBE_START arrives. Declaring the floor before the track is released to readers is the right order so a parked warm cache judges itself against where the live feed actually starts. Keeping the cache when Largest is absent (quiet catalog / empty track) matches the intentional “don’t wait forever” behavior covered by broadcast_rejoin_replays_a_current_warm_cache.

No better approach jumps out. Inferring the floor from the first served group (the path still open for pre-06 lite) would make a returning reader wait on an empty upstream; Largest is the signal the draft already gives for a live join. Expanding the stale-cache test across lite-06+ and every IETF draft, with the version in assertion messages, is the right regression net. Leaving pre-06 alone with an explicit skip note is fine unless someone later wants that tradeoff.

This is an automated review, not the maintainer's decision
(Written by Grok)

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