Repository navigation
refactor(rs): move every crate onto moq-clock - #6135
Conversation
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Production clock reads and timers in hang, moq-audio, moq-video, moq-gst, moq-rtsp, moq-srt, moq-hls, moq-shaper, moq-boy, moq-cli, moq-tokio, moq-relay, moq-quic, and moq-bench now go through moq-clock, and each finished crate gets the per-crate clippy ratchet. moq-clock gains timeout_at and interval_at, mirroring tokio's. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Outcome: left as a draft because one maintainer decision is open. The quest asks for clock support where third-party APIs (str0m, srt-tokio, winit) take std instants. My recommendation is a native-only moq-clock conversion to and from (Written by Claude Opus 5.5) |
Add native-only Instant::into_std and Instant::from_std, mapped through the runtime clock's origin. Use them for str0m (moq-ice, moq-rtc, moq-tokio webrtc), srt-tokio, winit, qlog, and retina, replacing the per-call-site host reads, and ratchet moq-ice and moq-rtc. Record the decision, finish the crates quest, and split the public SystemTime move into its own quest. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
# Conflicts: # Cargo.lock # rs/moq-gst/Cargo.toml
|
@codex review (Written by Claude Opus 5.5) |
|
Codex Review: Didn't find any major issues. More of your lovely PRs please. Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
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". |
|
Merging at
(Written by Claude Opus 5.5) |
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: f8a9d5e369
ℹ️ 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".
| pub(crate) fn into_std(at: Instant) -> Option<std::time::Instant> { | ||
| let base = std_base(); | ||
| match at.since_origin().checked_sub(LEAD) { | ||
| Some(after) => base.checked_add(after), | ||
| None => base.checked_sub(LEAD - at.since_origin()), |
There was a problem hiding this comment.
Map std conversions through the active ambient clock
When a Manual clock is installed or code runs under #[moq_clock::test], the ambient instant starts at Instant::ZERO, but this conversion still uses the runtime's std_base and subtracts the 2^32-second LEAD. On ordinary systems, converting any such near-zero instant therefore returns None and Instant::into_std() panics; the inverse also produces values on the runtime scale rather than the active clock's scale. Consequently, migrated third-party boundaries such as QlogConfig::into_stream, the ICE agent, and RTC dispatch cannot be exercised with the repository's controlled clocks. The conversion needs a stable std anchor belonging to the active simulator/manual backend.
AGENTS.md reference: AGENTS.md:L19-L20
Useful? React with 👍 / 👎.
# Conflicts: # quest/m1/time/README.md # rs/moq-cli/src/main.rs # rs/moq-relay/src/relay.rs
|
Merged
(Written by Claude Opus 5.5) |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: edb6866353
ℹ️ 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".
| //! the [`Stream`](super::Stream) drops, the device is released, and no | ||
| //! blocking thread is left pinned. | ||
|
|
||
| use moq_clock::Instant; |
There was a problem hiding this comment.
Preserve the active clock across capture callback threads
When capture runs under an installed Manual clock or the simulator, FrameChannel::new records an epoch from that controlled clock, but push is explicitly called from foreign callback threads where Instant::now() cannot discover the runtime-local clock and falls back to the host scale near LEAD. at() consequently assigns the first real camera frame a timestamp roughly 136 years after the controlled epoch, which capture_loop then publishes instead of the simulated acquisition time. Capture the active clock in the channel and read that same clock from callbacks so these device paths remain usable under mocked time.
AGENTS.md reference: AGENTS.md:L20-L20
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Declining. Foreign-thread pushes only come from real device backends (AVFoundation, ScreenCaptureKit, V4L2, WGC, Media Foundation), and those only run on an unpaused runtime, where the off-runtime fallback counts from the same origin as the runtime clock, so the epoch and every push stay on one timeline. Nothing pairs a controlled clock with a device thread: the simulator never runs device threads, the only Manual::install consumer is moq-ffi's testing feature, which does not build capture, and capture tests feed Synthetic::push_at with instants read in the async context. Carrying a runtime handle into every callback to enter it would add cost for a combination nothing uses; this matches the device-thread decision recorded in quest/m1/time/README.md.
(Written by Claude Opus 5.5)
# Conflicts: # quest/m1/time/crates.md
The test raced a direct std::time::Instant::now() against a moq-clock read, so it could flake under load. Its subject, moq-srt's host_instant helper, is gone; moq-clock's std_conversion_is_exact_on_a_running_clock checks the same conversion deterministically. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Merged
(Written by Claude Opus 5.5) |
|
Queued as trivial on head 3c91b56. Codex's last completed review stands: the only changes since are a quest-only conflict fix and one deleted flaky test. The head merges cleanly with current main. Main's new time-API uses since the merge base are in moq-ffi (no clippy.toml here) or in test modules this PR already allows, so the new disallowed lists shouldn't trip. (Written by Claude Opus 5.5) |
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The resolve wait it measures now runs on moq_clock::timeout, and the crate's ratchet bans tokio's Instant. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Merged
Both are mechanical applications of this PR's migration to code main added, so the last completed review stands. Checks on the merge: lint, fmt, clippy, docs, quest, markdown, and 9292 + 511 + 220 Rust tests pass. (Written by Claude Opus 5.5) |
ietf/session.rs: main's grant check judges the publisher's serving origin (#6259); keep this branch's serving() view on it, so the check registers no discovery interest. moq-rtc whep.rs: keep the watch-then-request resolve, moved onto moq-clock like the rest of the crate (#6135). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Main disallows tokio::time in moq-rtc since #6135. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Finishes
quest/m1/time/crates.md: every crate's production clock reads and timers move ontomoq-clock, and every crate except kio is ratcheted. The quest file is deleted; the publicSystemTimetomoq_clock::Wallmove is split into its own quest,quest/m1/time/wall.md.Changes
std::time::Instant,tokio::time::{Instant, sleep, sleep_until, timeout, timeout_at, interval, interval_at, Sleep, Interval, MissedTickBehavior}, andSystemTime::nowbecome theirmoq_clockequivalents in hang (example), moq-audio, moq-video, moq-gst, moq-rtsp, moq-srt, moq-hls, moq-shaper, moq-boy, moq-cli (including the new stats report), moq-tokio, moq-relay, moq-quic, moq-bench, moq-ice, and moq-rtc, including the macOS and Windows capture paths (unverified here: they do not build on Linux).Instantbeside async code on tokio time now readmoq_clock::now(), which falls back to the host clock off a runtime.timeout_atandinterval_at, mirroring tokio's, for the seventimeout_atsites and moq-shaper's delayed first report tick.Instant::into_stdandInstant::from_std, native only, mapped through the runtime clock's origin. They are exact on a running clock and keep only durations on paused tokio or the simulator.into_stdpanics outside std's range;from_stdsaturates. The crate docs anddoc/lib/rs/moq-clock.mdno longer say an instant never converts back.webrtc), srt-tokio's pacing, winit'sWaitUntil, qlog's epoch, and retina's arrival stamps convert withinto_std/from_stdat the call, so the per-site#[allow]s and moq-srt'shost_instanthelper are gone. noq's congestion controller trait keeps one#[allow(clippy::disallowed_types)], since the trait's signature is std's.std::thread::sleepon threads outside any runtime (audio buffer and driver, bench host, boy main, V4L2, X11) stays under a per-site#[allow]: such a thread has no ambient clock to wait on, and the simulator never runs it.clippy.tomlbanning direct clock reads and timers, matching moq-archive's. Crates that still exposeSystemTime(hang, moq-bench, moq-cli, moq-gst, moq-hls, moq-quic, moq-relay, moq-rtc, moq-tokio) allow that type until it moves tomoq_clock::Wall. Test modules, integration tests, and benches carry#[allow], as in moq-dev/moq#5987; their conversion is the m2 sweep.tokiodependency is now optional, behindtest-support, and moq-ice drops tokio'stimefeature.Decision
Settled by the maintainer (option 1): a native-only moq-clock conversion to and from
std::time::Instantthrough the runtime origin, withstd::thread::sleepkept under#[allow]on device threads. Recorded inquest/m1/time/README.md.Public API and wire
timeout_at,interval_at,Instant::into_std, andInstant::from_std. Additive.MIGRATE.mdentry.Checks
just checkon the merge withmainatee4653a507: passes (lint, fmt, docs, JS, bench harness, and 9317 + 516 + 223 Rust tests). An earlier run hitmoq-cliexport::redundant_importers_switch_through_bufferbloat_on_lite_07under heavy machine load; it passes alone and on every rerun.cargo nextest run -p moq-clock: the newtimeout_at,interval_at, and std conversion tests (exact on a running clock, durations on paused tokio, saturation) pass.Follow-ups
quest/m1/time/wall.md: move public wall times tomoq_clock::Wall, then banSystemTimein the remaining ratchets.tests::CLOCK) that the sim orManualcould replace (m2 sweep).(Written by Claude Opus 5.5)
🤖 Generated with Claude Code