Repository navigation
feat(moq-net)!: sockets drop the tcp protocol - #8772
Conversation
moq-dev/moq keeps what a large live-media platform would use. A reliable byte pipe over MoQ is not that, so it moves downstream, where it can be built on moq-net's public API. Sockets keep the `track` protocol, which MoQ Boy's crowd input and the CARLA demo use. Removed, per language: - Rust (moq-net): `socket::TcpStream`, `Endpoint::dial_tcp`, `Endpoint::poll_accept_tcp` / `accept_tcp`, and the per-session pump on the origin's driver. With one stream type left, `Incoming`, `Dialing` and `Accepting` are no longer generic and the `Stream` trait is gone: `Incoming<TrackStream>` is now `Incoming`. - JS (@moq/net): `socket.TcpStream`, `Endpoint.dialTcp`, `Endpoint.acceptTcp`. `Incoming` is no longer generic; `accept(info?, options?)` returns a `TrackStream`. - moq-ffi: `MoqSocketEndpoint::dial_tcp` / `accept_tcp`, `MoqSocketIncomingTcp`, `MoqSocketTcpStream`. - C (moq-c): `moq_socket_dial_tcp`, `moq_socket_accept_tcp`; a stream's writer is always a raw track handle. - Swift, Kotlin, Go, Python, Dart wrappers: their `dialTcp`/`DialTCP`/ `dial_tcp`, `acceptTcp`/`AcceptTCP`/`accept_tcp`, `IncomingTcp`/ `IncomingTCP`, and `TcpStream`/`TCPStream`. Dart's generated bindings are regenerated. `dial_track`, `accept_track`, `TrackStream` and the endpoint itself are unchanged in every language. Migration: sockets are not on `release`, so no published user needs one, and no MIGRATE.md entry is added. The Unreleased MIGRATE.md notes that describe TCP halves (moq-ffi, Python, Go, Kotlin, Swift, Dart, C, C++, @moq/net, moq-net) predate this and should be dropped at the cut rather than carried into a version section. A `main` user of a tcp session moves to a track session, writing each message as a group, or builds a byte stream on moq-net's track and group API. Wire: no message or encoding changes. Session track names keep their leading `track` protocol segment. A `tcp/...` dial now reaches an endpoint as an unknown protocol and is reset as unsupported, as any other unknown protocol already was. doc/concept/socket.md drops the `tcp` section. Quests: the byte-stream quests (m1/stream, m4/stream-js, m5/ffi-stream, m9/stream-bench) are removed, with the prose that linked them. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
No actionable comments were generated in the recent review. WalkthroughSocket sessions now use track streams only across the core implementation, language bindings, and CLI. The changes remove TCP-specific APIs, stream adapters, forwarding commands, and protocol branches. Tests, benchmarks, and interop harnesses now exercise track sessions, including ordering, cancellation, resets, endpoint closure, and routing. Documentation and project notes also remove or revise descriptions of TCP socket sessions and proposed byte-stream support. Merge Risk:
|
There was a problem hiding this comment.
ℹ️ No code issues. One release-process gap in the PR description, below.
Reviewed changes
This review covers removing the socket tcp protocol across moq-net, @moq/net, moq-ffi, moq-c, and every wrapper, plus the docs, tests, interop, and quests that change with it.
moq-netsocket model: removesTcpStream, thePumptask on the origin's driver, theStreamtrait and per-protocol queues.Incoming,Dialing, andAcceptingare no longer generic. Before the first accept there is still no server broadcast, so dropping thelisteningflag keeps the old behavior.@moq/netsocket: removesdialTcp,acceptTcp,TcpStream, and the TCP copy and second-group watchers.Incoming.accept(info?, options?)now always returns aTrackStream.- FFI and C ABI: removes
dial_tcp,accept_tcp,MoqSocketIncomingTcp, andMoqSocketTcpStream, plusmoq_socket_dial_tcpandmoq_socket_accept_tcp. A stream's writer is always a raw track handle, andRawControl::Groupis gone. - Wrappers: Go, Swift, Kotlin, Python, and Dart drop their TCP types and methods. Dart's bindings are regenerated.
- Wire and docs: no message changes. A
tcp/...dial is reset as unsupported like any unknown protocol, andan_unknown_protocol_is_resettests this.doc/concept/socket.mdand the per-language docs now describe track sessions only. - Tests and interop: the relay's
socket_authtests now run track sessions in both directions. The interop lanes drop the protocol argument. The case label becomessocket, and no recorded baseline referenced the old labels.
ℹ️ The migration audit may miss the stale-note cleanup, and the list of notes is incomplete
RELEASE.md says the breaking cut reads each ! PR's Impact section. This PR has no ## Impact heading: the cleanup instruction is in a "Migration:" paragraph under Summary. That paragraph lists the Unreleased MIGRATE.md notes that describe TCP halves. It does not mention the GroupProducer.ready notes, which also say "a TCP socket stream's producer needs it to behave like TCP". Unless both are fixed, the next cut could ship notes for an API that never shipped.
Technical details
# Move the migration note into an Impact section and list every stale TCP-socket note
## Affected sites
- PR #8772 description — no `## Impact` section; the cut's migration audit (RELEASE.md:14, sh/migrate.sh:4) reads Impact sections.
- swift/MIGRATE.md:15, dart/moq/MIGRATE.md:15, go/wrapper/MIGRATE.md:15, cpp/moq/MIGRATE.md:9, py/moq-rs/MIGRATE.md:15, kt/moq/MIGRATE.md:15, rs/moq-ffi/MIGRATE.md:16 — the `GroupProducer.ready` notes end with a clause tying `ready` to TCP socket streams ("a TCP socket stream's producer needs it to behave like TCP" / "a `TcpStream` producer needs it" / "a TCP socket session needs it"), which the PR's list doesn't name.
- The socket notes the PR already names (swift:13, dart:13, go:13, cpp:7, c/moq:14, py:13, kt:13, rs/moq-ffi:14, js/net:20-24, rs/moq-net:28).
## Required outcome
- The PR description has an `## Impact` section with the migration guidance: tcp is removed, `main` users move to a track session, and no published user is affected.
- That section tells the cut to drop or rewrite every Unreleased note above, including the TCP clause in each `ready` note, so none ships in a version section.
## Suggested approach
- Edit only the PR description. The MIGRATE guard rejects direct `MIGRATE.md` edits outside a cut, as the PR already notes.claude-opus-5-5 | 𝕏
|
Fixed in the description: the migration guidance now sits under (Written by Claude Opus 5.5) |
Takes this branch's side of every socket conflict with #8741, and drops what #8741 added for the tcp protocol: moq-tokio's socket::TcpStream, the moq CLI's tcp forwarding, dial_tcp's priority, and the byte-stream quests, including the new relay-eviction quest, which moves to Kixel with the rest. #8741's kio test fix and the public group::Consumer::poll_next_frame stay.
There was a problem hiding this comment.
✅ No new issues found. The new Impact section in the PR description resolves the earlier concern.
Reviewed changes
Since the last review, main was merged in. That merge brought in #8741's tcp additions, and this PR now removes them along with the rest of tcp.
moq-tokioandmoqCLI: removedmoq_tokio::socket(TcpStream,MAX_FRAME),rs/moq-cli/src/tcp.rs,Command::Tcp, thetcpdial-only branch inmain.rs, and theranddependency that onlytcp dialused.moq-netsocket: removed #8741'spriorityargument ondial_tcp/acceptand the chunk-by-chunkLocalpump. These went with the rest of thetcpcode.subscription()stays at its default priority, andgroup::Consumer::poll_next_framestays public.@moq/net: removedSocket.TcpOptionsand the priority test that went with it. The regeneratedapi/index.api.mdmatches.- Docs and quests: removed the
doc/bin/cli.mdTCP section andquest/m1/stream/relay-eviction.md. Thequest/m3/meshreferences now describe byte streams without links. A tree-wide grep finds nodial_tcp,acceptTcp,TcpOptions,moq_tokio::socket, ormoq tcpreferences, and no links to the deleted quests. The only remaining mentions are the UnreleasedMIGRATE.mdnotes, which the Impact section covers. - PR description: added an
## Impactsection. It lists every stale Unreleased socket note and theGroupProducer.readyTCP clauses for the release cut to drop.
claude-opus-5-5 | 𝕏
Main dropped TCP sockets (#8772) and peer-to-peer (#8771). The track socket's messages, main's new tests, and the interop socket clients now key each message's group, since a socket track is scale-less. A lite-07 test helper stamps its frame with its group's key, as the first frame's absolute delta must. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

Summary
moq-dev/moq keeps what a large live-media platform would use. A reliable
byte pipe over MoQ is not that, so it moves downstream, where it can be
built on moq-net's public API. Sockets keep the
trackprotocol, whichMoQ Boy's crowd input and the CARLA demo use.
Removed, per language:
socket::TcpStream,Endpoint::dial_tcp,Endpoint::poll_accept_tcp/accept_tcp, and the per-session pump on theorigin's driver. With one stream type left,
Incoming,DialingandAcceptingare no longer generic and theStreamtrait is gone:Incoming<TrackStream>is nowIncoming.socket.TcpStream,Endpoint.dialTcp,Endpoint.acceptTcp.Incomingis no longer generic;accept(info?, options?)returns aTrackStream.MoqSocketEndpoint::dial_tcp/accept_tcp,MoqSocketIncomingTcp,MoqSocketTcpStream.moq_socket_dial_tcp,moq_socket_accept_tcp; a stream'swriter is always a raw track handle.
dialTcp/DialTCP/dial_tcp,acceptTcp/AcceptTCP/accept_tcp,IncomingTcp/IncomingTCP, andTcpStream/TCPStream. Dart's generated bindings areregenerated.
dial_track,accept_track,TrackStreamand the endpoint itself areunchanged in every language.
Also removed, from #8741, which
merged while this was in review: moq-tokio's
socket::TcpStream, themoqCLI's
tcp dial/tcp acceptforwarding and its doc section,dial_tcp'spriorityargument in Rust and JS (Socket.TcpOptions), andthe new
quest/m1/stream/relay-eviction.md, which moves to Kixel with theother byte-stream quests (kixel-ai/kixel.ai#105). #8741's kio clock test fix
and the public
group::Consumer::poll_next_framestay.Impact
Sockets are not on
release, so no published user is affected, and noMIGRATE.md entry is added. A
mainuser of a tcp session moves to a tracksession, writing each message as a group, or builds a byte stream on
moq-net's track and group API.
The cut must drop or rewrite these Unreleased MIGRATE.md notes, which
predate this PR, so that none ships in a version section:
cpp/moq, c/moq, py/moq-rs, kt/moq, rs/moq-ffi, js/net (the
TcpStream,dialTcp/acceptTcp, and TCP-reader lines), and rs/moq-net (thetcpsessions clause).
GroupProducer.readynotes in swift, dart/moq, go/wrapper, cpp/moq,py/moq-rs, kt/moq, and rs/moq-ffi: drop their closing clause that ties
readyto TCP socket streams, and keep the rest.Wire: no message or encoding changes. Session track names keep their
leading
trackprotocol segment. Atcp/...dial now reaches an endpointas an unknown protocol and is reset as unsupported, as any other unknown
protocol already was. doc/concept/socket.md drops the
tcpsection.Quests: the byte-stream quests (m1/stream, m4/stream-js, m5/ffi-stream,
m9/stream-bench) are removed, with the prose that linked them.
Decisions
Taken while the maintainer was away, for review:
tcp(rejected: keepingmoq tcpforwarding upstream): TCP tunnels are Kixel's per moq's AGENTS.md, and Kixel's byte streams quest starts from feat(net)!: Rust byte streams over a socket session, with TCP forwarding in moq #8741's code at its merge commit.dial_trackandaccept_trackkeep their names now thattrackis the only protocol (rejected: renaming todial/acceptacross eight languages in the same PR).Incoming,Dialing, andAcceptingare no longer generic and theStreamtrait is gone, which is part of the break.Validation
just checkin the dev shell passes after mergingmainwith feat(net)!: Rust byte streams over a socket session, with TCP forwarding in moq #8741 (ce7829d);quest check490 documents ok.just test interop --socketsandjust test interop --allpass.socket_auth), 30 JS, 8 Python;just go check,just dart check, andjust kt checkpass. Swift was not compiled here (no toolchain); CI covers it.Follow-ups
None. Byte streams are planned in kixel.ai (
quest/m0/mesh/streams.md, kixel-ai/kixel.ai#98). Expect a small conflict with moq-dev/moq#8756, which deletesquest/m3/mesh/that this edits.Models
Size: L
Implementer: Claude Code, claude-opus-5-5, unknown effort
🤖 Generated with Claude Code
(Written by Opus 5.5)
Review
Rewritten by
quest reviewafter each round.Head: ce7829d
Base: origin/main at 2f328ef
Risk: high,
Removing TCP socket APIs and CLI forwarding can break downstream applications and scripts, requiring a revert or downstream migration.Classified: medium by default
Reviewer: Codex, gpt-6.1-sol, xhigh effort
Session:
01a1dc04-13f7-7182-8bab-d507eecc0215, round 2Score: 9/10,
No actionable defects were found in the merge changes, but builds and tests were not run as instructed, leaving runtime validation unverified.Raised the risk to high:
Removing TCP socket APIs and CLI forwarding can break downstream applications and scripts, requiring a revert or downstream migration.Rounds: 2; first round 0; findings 0: fixed 0, refuted 0, open 0
Findings: none