Skip to content

refactor(net)!: return the next deadline from driver polls - #3828

Merged
kixelated merged 2 commits into
mainfrom
driver-followups
Sep 21, 2026
Merged

kixelated merged 2 commits into
mainfrom
driver-followups

Conversation

@kixelated

@kixelated kixelated commented Sep 21, 2026

Copy link
Copy Markdown
Collaborator

Problem

Follow-ups from #3825. time::Driver split its answer across poll(now, waiter) -> Poll<Output> and a separate timeout(), so every turn took two calls (and two clock locks), and "finished" had a different shape from Session::closed. The adapter loop that sleeps until the next deadline was copied into moq-tokio, moq-wasm, moq-ffi, and a test-runtime feature.

Approach

poll(now, waiter) -> Result<Option<Instant>, Error>: Ok(Some(at)) is the next deadline, Ok(None) waits on external activity only, and Err is terminal, with Error::Closed for a clean finish (the same value Session::closed reports). One moq_net::time::run(driver) -> Error lives next to the trait, since moq-net already depends on web-async for the wasm Instant; moq-uring keeps its own loop on the worker timer heap.

Impact

  • Breaking moq-net: time::Driver loses Output and timeout(); Driver::poll and origin::Driver::poll return Result<Option<Instant>, Error>. New time::run. The test-runtime feature is removed.
  • Breaking moq-tokio, moq-wasm: the runtime modules are removed; callers use moq_net::time::run. moq-mux, moq-srt, moq-stats, moq-video drop their moq-tokio dev-dependency.
  • moq_uring::Handle::run resolves with the terminal Error.
  • The relay's WebSocket handler maps Error::Closed back to Ok(()) so a clean close is not logged as a failure.
  • No wire, TypeScript, or foreign ABI changes.

Validation

just check and just test pass (4737 Rust tests, JS, Python).

Notes

web-async stays, but only for time: moq-net needs the performance.now()-backed Instant and setTimeout sleep on wasm, which is exactly the cfg split the crate exists for. Its Lock uses are swapped for kio::Lock (which gains a Default impl), so they now sit under loom's model too.

The native JS smoke client follow-up from #3825 was already fixed on main by #3819.

(written by Claude Opus 5)

🤖 Generated with Claude Code

`time::Driver::poll(now, waiter)` now returns `Result<Option<Instant>, Error>`:
the next deadline while live, and the terminal error once finished
(`Error::Closed` for a clean finish), matching `Session::closed`. The
separate `timeout()` accessor and `Output` type are gone.

`moq_net::time::run` replaces the identical adapter loops in moq-tokio,
moq-wasm, moq-ffi, and the test-runtime feature; moq-uring keeps its own on
the worker timer heap.

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

Copy link
Copy Markdown
Collaborator Author

MERGE

Positive improvement? Yes. This is the right cleanup after #3825. Folding the next deadline into poll removes the two-call (and two-lock) turn, and collapsing four nearly identical adapter loops (moq-tokio, moq-wasm, moq-ffi, time::test) into one moq_net::time::run is real complexity gone, not moved. Mapping a clean finish to Error::Closed also aligns the driver terminal with Session::closed, which the relay's ended() helper then handles cleanly.

Worth the complexity? Yes — this reduces surface area. Losing Output and timeout() is a break, but it is the natural second step while the explicit-time API is still settling, and the net diff shrinks the tree (~100 lines deleted, test-runtime gone, several crates drop a moq-tokio dev-dep). Call sites become one spawn of moq_net::time::run; custom loops (moq-uring) keep their own heap and only change the poll return shape.

Different approach? A dedicated step enum (Deadline / Wait / Done(Error)) would read clearer than Result<Option<Instant>, Error>, where Err means "finished" rather than "failed." The chosen encoding is still fine: three outcomes, documented on the trait, and matches how callers already want to branch. Not worth another break for naming alone. Keeping separate poll + timeout would preserve the duplication this PR exists to kill.

Nits (non-blocking):

  • doc/lib/rs/moq-net.md still says "moq-tokio and moq-wasm drive sessions for their callers" after those runtime modules are removed — worth a one-line fix to point at moq_net::time::run.
  • CI was still running at review time; author reports just check / just test green.

Ship it.

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

@moq-bot

moq-bot Bot commented Sep 21, 2026

Copy link
Copy Markdown
Contributor
  1. Breaking time::Driver and runtime removals target main but need dev (rs/moq-net/Cargo.toml:8, AGENTS.md#Development). Retarget this PR to dev, set upstream to origin/dev, then rebase.
    Verdict: request changes
    (Written by Muse Spark)

New%20session%20-%202026-09-21T11%3A54%3A20.358Z
opencode session  |  github run

@coderabbitai

coderabbitai Bot commented Sep 21, 2026

Copy link
Copy Markdown
Contributor

Review Change StackReview Change Stack

Understand this PR’s impact

Explore downstream dependencies and potential security impact with Blast Radius.

View blast radius →

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: 3e78372b-cc88-47c4-9c8d-5f660ab924bb

📥 Commits

Reviewing files that changed from the base of the PR and between 162da68 and f5b0b37.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (44)
  • doc/lib/rs/moq-net.md
  • rs/moq-e2ee/Cargo.toml
  • rs/moq-e2ee/tests/support/harness.rs
  • rs/moq-ffi/src/lib.rs
  • rs/moq-ffi/src/origin.rs
  • rs/moq-ffi/src/runtime.rs
  • rs/moq-ffi/src/session.rs
  • rs/moq-hls/src/export/mod.rs
  • rs/moq-hls/src/export/upstream.rs
  • rs/moq-hls/src/server/mod.rs
  • rs/moq-mux/Cargo.toml
  • rs/moq-mux/src/source.rs
  • rs/moq-net/Cargo.toml
  • rs/moq-net/src/client.rs
  • rs/moq-net/src/driver.rs
  • rs/moq-net/src/lib.rs
  • rs/moq-net/src/model/origin.rs
  • rs/moq-net/src/server.rs
  • rs/moq-net/src/time.rs
  • rs/moq-net/tests/support/harness.rs
  • rs/moq-relay/src/websocket.rs
  • rs/moq-rtc/src/egress.rs
  • rs/moq-srt/Cargo.toml
  • rs/moq-srt/src/dial.rs
  • rs/moq-srt/src/server.rs
  • rs/moq-srt/src/ts.rs
  • rs/moq-stats/Cargo.toml
  • rs/moq-stats/src/aggregate.rs
  • rs/moq-stats/src/consume.rs
  • rs/moq-stats/src/produce.rs
  • rs/moq-tokio/src/client.rs
  • rs/moq-tokio/src/lib.rs
  • rs/moq-tokio/src/origin.rs
  • rs/moq-tokio/src/runtime.rs
  • rs/moq-tokio/src/server.rs
  • rs/moq-uring/benches/session_lite.rs
  • rs/moq-uring/src/worker.rs
  • rs/moq-uring/tests/session.rs
  • rs/moq-uring/tests/web.rs
  • rs/moq-video/Cargo.toml
  • rs/moq-video/src/decode/consumer.rs
  • rs/moq-wasm/README.md
  • rs/moq-wasm/src/lib.rs
  • rs/moq-wasm/src/runtime.rs
💤 Files with no reviewable changes (11)
  • rs/moq-ffi/src/lib.rs
  • rs/moq-srt/Cargo.toml
  • rs/moq-tokio/src/lib.rs
  • rs/moq-net/Cargo.toml
  • rs/moq-tokio/src/runtime.rs
  • rs/moq-stats/Cargo.toml
  • rs/moq-ffi/src/runtime.rs
  • rs/moq-video/Cargo.toml
  • rs/moq-e2ee/Cargo.toml
  • rs/moq-mux/Cargo.toml
  • rs/moq-wasm/src/runtime.rs

Included review availability: Your plan provides up to 4 included reviews per hour; 2 remain after this review.


Walkthrough

The PR changes moq_net::time::Driver to return optional deadlines or terminal moq_net::Error values. It adds a shared asynchronous moq_net::time::run function and removes test-only and crate-local runtime runners. Tokio, browser, FFI, relay, and uring integrations now use the shared runner. Origin and session drivers adopt the new polling contract. Tests, documentation, harnesses, benchmarks, and development dependencies are updated accordingly.

Priority: ➖ Normal

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 76.60% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 47 functions across 31 files. (2 skipped:… Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
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.
Title check ✅ Passed The title clearly summarizes the main breaking change: driver polls now return the next deadline.
Description check ✅ Passed The description directly explains the problem, implementation, breaking API changes, impact, and validation for the changeset.
Full details: Docstring Coverage

Explanation

Docstring coverage is 76.60% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 47 functions across 31 files. (2 skipped: 2 unsupported.)

  • Fix all pre-merge checks with AI
✨ Finishing Touches
✨ Simplify code
  • Commit to this branch
  • Create a new PR

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.

Leaves web-async serving only the browser clock in moq-net, and puts these
locks under loom's model. kio::Lock gains the Default impl the swap needs.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@kixelated
kixelated enabled auto-merge (squash) September 21, 2026 12:07
@moq-bot

moq-bot Bot commented Sep 21, 2026

Copy link
Copy Markdown
Contributor
  1. Breaking time::Driver plus moq-tokio/moq-wasm runtime removals target main but need dev (rs/moq-net/Cargo.toml:8, AGENTS.md#Development). Retarget this PR to dev, set upstream to origin/dev, then rebase.
  2. WebSocket subprotocol docs now attach to ended, leaving negotiate_subprotocol undocumented (rs/moq-relay/src/websocket.rs:232, AGENTS.md#Required). Move the pick-a-subprotocol block above negotiate_subprotocol and keep only the terminal-error doc on ended.
  3. Doc still says "moq-tokio and moq-wasm drive sessions for their callers" after those runtime modules are removed (doc/lib/rs/moq-net.md:60, AGENTS.md#Required). Delete that sentence or point at moq_net::time::run.
  4. Description omits required Alternatives and Follow-ups sections (CONTRIBUTING.md#PRs). Add both sections, stating none if there are none.

Verdict: request changes
(Written by Muse Spark)

New%20session%20-%202026-09-21T12%3A07%3A27.584Z
opencode session  |  github run

@kixelated
kixelated merged commit d2f881b into main Sep 21, 2026
20 checks passed
@kixelated
kixelated deleted the driver-followups branch September 21, 2026 12:26
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