Skip to content

Migrate network timing onto moq-clock - #5681

Merged
kixelated merged 33 commits into
mainfrom
quest/m1/time/net
Oct 17, 2026
Merged

kixelated merged 33 commits into
mainfrom
quest/m1/time/net

Conversation

@kixelated

@kixelated kixelated commented Oct 16, 2026 •

Copy link
Copy Markdown
Collaborator

Problem

moq-net, moq-mux, moq-stats, moq-room, and moq-ffi read std/tokio/web-async clocks directly, so tests mix clocks (paused tokio does not pause std::time::Instant) and the browser has no std clock.

Approach

  • migrate moq-net, moq-mux, moq-stats, moq-room, and moq-ffi to the shared logical moq-clock
  • start the runtime clock 2^32 s past Instant::ZERO, like std's since-boot Instant, so now() - d never underflows during a process's first seconds; the simulator still starts at zero
  • give each simulated ambient clock, and each paused tokio runtime counting from its own origin, its own stable monotonic/wall anchor
  • read the browser clock through web_async::time even without moq-clock's runtime feature, so moq-net without async works in the browser
  • remove the former moq-net simulator crates and migrate their test harnesses, porting idle() to moq_clock::sim::idle so settling waits for quiescence
  • preserve moq-net's runtime-free core while enabling ambient timers only with its async feature
  • ratchet production clock reads in the migrated crates with Clippy configuration (benches that time real work opt out)
  • update in-tree callers to the breaking logical Instant API, including the feature-gated ones: moq-wasm, moq-relay's io-uring path, moq-cli's play, and moq-audio/moq-video capture
  • describe the logical instant in the moq-wasm guide
  • port main's resume-aware playout (fix(play)!: drain clean encoder segments before resuming #5687) to the logical clock; moq-cli now depends on moq-clock outside the play feature, since play/timeline.rs compiles without it

Impact

  • Breaking Rust API: timing-facing std::time::Instant / Tokio instant parameters and returns are now moq_clock::Instant across the affected crates and callers.
  • moq-clock: runtime instants read 2^32 s past zero at the origin; browser reads no longer need the runtime feature; anchor() is per paused runtime, and the shared one reads real time so an advanced paused runtime cannot skew it; new sim::idle().
  • Wire impact: none.

Decisions

  • ✅ Use a fixed offset: the moq-clock runtime origin starts 2^32 s past Instant::ZERO (chosen by the maintainer).

Why 2^32 s

Counting from zero at the first read broke now - d near startup: the playout edge (now + buffered - delay) fell back to now, decode-ahead waits were skipped, and capture fixtures could not name a clock that began seconds ago. 2^32 s (~136 years) exceeds any plausible lookback and leaves ~448 years of u64 nanosecond range ahead. The simulator keeps Instant::ZERO for fixed test coordinates.

Tests

  • ✅ moq-clock startup_reads_can_look_back: now() - 1h right after startup, inside a fresh paused runtime and outside any runtime; fails with a zero origin
  • ✅ moq-clock paused_runtimes_own_their_anchors: fails without per-runtime anchors
  • ✅ moq-clock a_later_paused_runtime_does_not_skew_the_anchor: fails when the shared anchor reads a paused clock
  • ✅ moq-net unit_tests_freeze_the_cache_clock: cache staleness stays frozen outside the simulator in unit tests and loom, as on main
  • ✅ moq-srt a_late_payload_keeps_its_past_host_instant; moq-mux simulated_clock_preserves_logical_boundaries now asserts the exact stepped wall (fails with the old SystemTime::now test fallback)
  • ✅ moq-clock idle_waits_for_every_timer, and mesh_withdraw settling on sim::idle()
  • ✅ moq-clock browser reads_without_runtime (just rs wasm-test --no-default-features run, in CI)
  • ✅ just rs capture-test: 467 passed on the final head (16 failed with a zero origin)
  • ✅ just rs play: 196 passed on the final head (4 failed with a zero origin)
  • ✅ moq-clock 56 and moq-net 2,258 on the final head; earlier: moq-net, moq-mux, moq-clock, moq-stats, moq-room, moq-ffi, moq-tokio, moq-hls, moq-archive, moq-transcode: 4,879 passed
  • ✅ just rs net-features, just rs tokio-features --all, workspace clippy, capture/uring/wasm/play clippy

Follow-ups

  • The remaining controlled-time migrations stay tracked by the parent time epic, including the video capture stream's own std epoch.

(Written by GPT-5.4, updated by Claude Opus 5.5)

kixelated and others added 2 commits October 15, 2026 21:35
@kixelated
kixelated marked this pull request as ready for review October 16, 2026 06:10
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 16, 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-17T09:09:55.681516Z 1edfc4c New commits
ℹ️ 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.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 4a239bb970

ℹ️ 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".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread rs/moq-clock/src/runtime.rs Outdated
Comment thread rs/moq-clock/src/runtime.rs
kixelated and others added 3 commits October 16, 2026 10:14
# Conflicts:
#	Cargo.lock
#	quest/m1/time/relay-seam.md
#	quest/m1/time/uring.md
#	rs/moq-ffi/src/session.rs
#	rs/moq-ffi/src/video.rs
#	rs/moq-mux/src/jitter.rs
#	rs/moq-tokio/Cargo.toml
…browser clock without timers

A paused runtime counting from its own origin now keeps its own anchor, so a
later runtime never maps instants through one an earlier runtime advanced.
Browser reads go through web_async::time even without the runtime feature,
since std has no clock there; moq-net built without `async` relies on it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
moq-wasm and moq-relay's io-uring path pass the logical instant, the benches'
paused timers run on moq-clock, and their real-time measurements opt out of the
clock ratchet.

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

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b7711ee7cf

ℹ️ 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".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread rs/moq-wasm/src/lib.rs Outdated
kixelated and others added 3 commits October 16, 2026 10:35
The playout timeline already took moq-clock instants; its callers in the play
feature now read and sleep on the same clock, converting to the host clock
only at winit's wait.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
moq-mux's clock and rate control take moq-clock instants, so the capture
features' callers read the same clock. Checkpoint: the capture clock fixtures
still need instants before the runtime clock's origin.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
# Conflicts:
#	quest/m1/time/README.md
#	quest/m1/time/relay-seam.md

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 50d783b9ec

ℹ️ 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".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread rs/moq-clock/src/runtime.rs Outdated
kixelated and others added 3 commits October 16, 2026 11:28
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Counting from zero at the first read made `now() - d` unrepresentable during a
process's first seconds, which broke playout scheduling and the capture
fixtures. The runtime clock now reads like std's since-boot Instant; 2^32 s
(~136 years) outlasts any lookback and leaves ~448 years of range. The
simulator still starts at zero.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
# Conflicts:
#	rs/moq-net/src/model/origin.rs
@kixelated

Copy link
Copy Markdown
Collaborator Author

@codex review

(Written by Claude Opus 5.5)

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Nice work!

Reviewed commit: 18d1933f83

ℹ️ 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".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

# Conflicts:
#	rs/moq-net/src/model/origin.rs
@kixelated

Copy link
Copy Markdown
Collaborator Author

@codex review

(Written by Claude Opus 5.5)

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 2606f45256

ℹ️ 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".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread rs/moq-net/tests/mesh_withdraw.rs Outdated
kixelated and others added 2 commits October 16, 2026 12:09
The global anchor now reads the host's real clock, so a paused runtime
that shares the origin and advances cannot skew it for unpaused callers.
Port moq_net_sim::idle to moq_clock::sim::idle so mesh_withdraw settles
on quiescence instead of a fixed 60 s sleep.

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

Copy link
Copy Markdown
Collaborator Author

@codex review

(Written by Claude Opus 5.5)

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 3330cd4b09

ℹ️ 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".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread rs/moq-net/src/model/clock.rs
Outside the simulator, unit tests and loom read the host clock for cache
staleness, so a preempted test could age groups it never stepped.
Restore main's frozen clock there, reading simulated time inside sim::run.

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

Copy link
Copy Markdown
Collaborator Author

@codex review

(Written by Claude Opus 5.5)

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: dfb102aa7f

ℹ️ 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".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread rs/moq-srt/src/server.rs Outdated
Comment thread rs/moq-mux/src/clock.rs Outdated
@kixelated

Copy link
Copy Markdown
Collaborator Author

Status for c6049f4:

  • Merged main after the queue dropped this for a conflict with fix(play)!: drain clean encoder segments before resuming #5687. Ported its resume-aware playout (play/media.rs, timeline.rs, video.rs) to moq_clock::Instant; moq-cli now depends on moq-clock outside the play feature because play/timeline.rs compiles without it. Main's new sim tests in moq-net and the relay auth test moved to moq_clock.
  • Fixed Codex's uring finding: worker deadlines are anchored before driver.poll.
  • Restored this PR's description, which an earlier edit had replaced with another PR's text by mistake.
  • just check passed on the merge (8,191 workspace tests, capture/play/py suites). Codex reviewed b5bef1f (one finding, fixed); a local codex review of the fix commit found no issues.
  • TS validation fails here with the same missing-audio symptom failing on many unrelated PRs today; it is not a required check.
  • moq-relay::drills bursts_cross_a_transport_peer::impaired flaked locally (4 of about 55 runs here; main flaked 2 of 22 with a different panic in the same impaired transport lane). Worth a follow-up.

Public API: breaking, timing parameters and returns move to moq_clock::Instant. Wire: none.

(Written by Claude Opus 5.5)

@kixelated
kixelated enabled auto-merge October 17, 2026 06:37
@kixelated
kixelated added this pull request to the merge queue Oct 17, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Oct 17, 2026
@kixelated

Copy link
Copy Markdown
Collaborator Author

The queue dropped c6049f4 because PRs ahead of it (#5833, #5708) added tests on the removed moq_net_sim. Merged main again and moved those tests to moq_clock. just check passed (8,264 workspace tests plus capture/play/py suites), and Codex reviewed 1f59e14 with no findings. Re-arming auto-merge on that head.

(Written by Claude Opus 5.5)

@kixelated
kixelated enabled auto-merge October 17, 2026 08:13
kixelated and others added 2 commits October 17, 2026 01:44
# Conflicts:
#	rs/moq-net/src/auth.rs
#	rs/moq-net/src/ietf/session.rs
#	rs/moq-net/src/lite/publisher.rs
#	rs/moq-net/tests/integration/extensions.rs
An origin always holds updates now that it has no undriven clock, so the
test waits on the simulated clock like its re-price sibling.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@kixelated
kixelated disabled auto-merge October 17, 2026 09:10
@kixelated
kixelated enabled auto-merge October 17, 2026 09:10
@kixelated

Copy link
Copy Markdown
Collaborator Author

Merged main again for 1edfc4c (conflicts with #5695's auth renewal tests, ported to moq_clock). One real interaction: #5695's an_auth_swap_is_an_update was a sync test that read an update with no hold, relying on the origin skipping the hold when its clock was never driven. This branch removes that undriven-clock case, so the test now waits out the hold on the simulated clock like a_reprice_is_an_update. just check passed (8,404 workspace tests). Codex reviewed this head with no findings.

Pre-existing flakes seen on main too: ietf::publisher::tests::a_reset_renewal_ends_only_its_request (1 in 44 stress runs on main) and the impaired relay drill tracked in quest/m1/test-flakes-2/relay-burst-impaired.md.

(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 7bdcd13 Oct 17, 2026
13 of 14 checks passed
@kixelated
kixelated deleted the quest/m1/time/net branch October 17, 2026 10:08
kixelated added a commit that referenced this pull request Oct 17, 2026
#5681 replaced moq_net_sim and crate::time::Clock with moq-clock and
Deadlines, and connect/accept now take a moq_net::time::Instant. The
receive-credit tests added here still used the old names.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
kixelated added a commit that referenced this pull request Oct 17, 2026
Moves this branch's tests onto moq_clock (#5681) and points main's new
latest() reads at the internal sequence.

Also derives the wrappers' next group from largest(), with no new API:
moq-json snapshot edits admit groups below an end declared ahead again,
and the moq-mux container producer seeds its counter from the track it
wraps, so a discontinuity no longer numbers below the track's groups.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
kixelated added a commit that referenced this pull request Oct 17, 2026
#5681 replaced moq_net_sim with moq_clock.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
kixelated added a commit that referenced this pull request Oct 17, 2026
Carries the NEW_GROUP request from #5708 through the counted demand and
the test fold, moves the tests onto moq-clock from #5681, and regenerates
the Dart bindings.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
kixelated added a commit that referenced this pull request Oct 18, 2026
Main replaced moq-net-sim with moq-clock's simulator (#5681).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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