M3: Robustness, multi-viewer, full error matrix #5
Loading…
Reference in a new issue
No description provided.
Delete branch "m3-robustness"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Stacked on top of PR #4. Targets
m2-webrtc-core-integrationso M2's review cadence isn't blocked.Acceptance criterion (from design)
Met in this PR. Verified by the new
TestIntegration_FiveViewerFanout(5 Pion subscribers attached to one process, each receives RTP, every peer is reaped ononProcessStop).Multi-viewer correctness
streamID → resourceID → Peertwo-level index in the Handler (was a single flat map). Per-stream and total caps are now separately enforceable.Peer.Done()channel — read-only view of the existing close signal. Lets external indexes await teardown without polling.awaitPeerClosegoroutine per peer — when Pion'sOnConnectionStateChangetriggerspeer.Close()after ICE failure/disconnect, the index entry is removed and the counter ticks back down. No leaks if a browser rage-quits.Subsystem.SetTeardownHook(fn)— process stop drives all subscribed peers to close before their Sources go away, closing the "subscribers fan out into a closed channel" race the design's §6 calls out.corewebrtc.DefaultConfig(32). Overridable viaNewHandlerWithCaps.Error matrix (design §6)
400/404/201 paths unchanged.
WHEP spec compatibility additions
PATCH /whep/:id/:resourcefor trickle-ICE; readsapplication/trickle-ice-sdpfrag, forwards eacha=candidate:line viapeer.AddICECandidate.OPTIONSpreflight answered on every WHEP route.Access-Control-Allow-{Origin,Methods,Headers}+Access-Control-Expose-Headers: Location, ETag) on every response, so browser-side WHEP players living on a different origin can subscribe.ETagheader on the Subscribe response (some WHEP servers expect it for resumption / If-Match).Test coverage
New tests:
TestIntegration_FiveViewerFanoutTestSubsystem_TeardownHookFiresOnProcessStopTestHandler_Subscribe_406OnCodecMismatchTestHandler_Subscribe_503OnTotalCapTestHandler_Subscribe_503OnPerStreamCapTestHandler_Trickle_404WhenUnknownTestHandler_PreflightCORSTestHandler_RegisterMountsAllRoutesTestHandler_Close_DrainsPeersTestRequireH264AndOpusUpdated:
TestHandler_Unsubscribe_204WhenUnknown(was_404WhenUnknown).Out of scope for this PR
/api/v3group still inherits Core's JWT, so it isn't unprotected.-map 0:v:0/0:a:0hardcoding) — separate small PR.Commits
Co-authored with Claude Opus 4.7.
Major Handler rewrite implementing the design's M3 acceptance criteria ('5 concurrent viewers, all error paths correct, clean teardown'): Multi-viewer correctness: - streamID -> resourceID -> Peer two-level index (was flat) - per-stream peer cap alongside total cap, defaults match the design's '5–8 viewer' target (8/stream, total from corewebrtc) - per-peer awaitPeerClose goroutine watches Peer.Done() so ICE failures yank the index entry + decrement the counter (no leaks) - tearDownStreamPeers callback (registered with Subsystem in NewHandler) drives all peer closes when the source process stops Error matrix from design §6: - 406 on codec mismatch (offer missing H264 or Opus rtpmap) - 504 on ICE gathering timeout (passthrough from CreatePeerFromSources) - 204 on DELETE unknown resource (idempotent per WHEP spec; was 404) - 503 on per-stream cap reached (separate body from total-cap 503) - 400 on missing/empty body (unchanged) - 404 on unknown stream (unchanged) WHEP spec compatibility: - PATCH /whep/:id/:resource for trickle-ICE - OPTIONS preflight on every WHEP path - CORS Allow-Origin/Methods/Headers + Expose-Headers (Location, ETag) - ETag header on Subscribe response Defensive nil-peer guards in tearDown / Close paths so a partial state doesn't panic. Refactor: 134 -> 341 lines on handler.go but the surface is the same (NewHandler/Register/Subscribe/Unsubscribe/Close); existing callers continue to work. Pre-M3 test 'Unsubscribe_404WhenUnknown' renamed and updated to the new 204 expectation. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>Merged into
mainvia direct push as part of the v0.1.0-dragonfork release. Branch commits are reachable from main; closing this PR. Release: https://forge.wilddragon.net/zgaetano/datarhei-dragonfork-core/releases/tag/v0.1.0-dragonforkPull request closed