Harden LA publishers and add multi-relay guide
Some checks are pending
ci-gates / checks (push) Waiting to run
deploy-cloudflare / checks (push) Waiting to run
deploy-cloudflare / deploy (push) Blocked by required conditions

This commit is contained in:
Conrad Kramer 2026-06-10 01:28:15 -07:00
parent 5d6f77f868
commit cfc4902016
No known key found for this signature in database
13 changed files with 1430 additions and 402 deletions

View file

@ -0,0 +1,50 @@
# ECP-0121: Greedy Multi-Relay Streams
Status: Draft
## Problem statement
Live streams should be publishable to more than one relay at once so viewers can pick the fastest
path and regional relays can mirror each other. The current public directory shape only exposes one
`relay_url` per stream, which encourages duplicate publishers when we want redundancy. For OTA
sources, duplicate publishers are dangerous because each one opens another tuner read.
## Constraints
- Preserve the existing `relay_url`, `broadcast_name`, and `track_name` fields for deployed web,
archive, and manual watch links.
- Keep those primary fields as the compatibility contract; `relays[]` is additive and optional for
consumers.
- Do not duplicate HDHomeRun source reads to get multi-region relay presence.
- Let the public directory advertise multiple relays before every consumer implements racing.
- Keep rollback simple: clients can ignore `relays[]` and keep using the primary legacy fields.
## Decision
Add an ordered `relays[]` candidate list to public stream entries and stream upserts. Stream upserts
continue to require the primary legacy fields; the first relay is mirrored into those fields and
remains the primary/default path. `control-bridge-web` now forwards all relay transports already
present in a control announcement instead of flattening to the first relay only. Current consumers
can keep reading the legacy fields until they explicitly add relay racing.
The intended next step is a single ingest/fanout publisher: read the source once, encode/fragment
once, publish the same stream objects to LAX and NYC relay sessions, and optionally let relays mirror
to each other. Consumers can then race candidates greedily by availability/latency without causing
extra source reads.
## Alternatives considered
- Start one publisher per relay. Rejected because it duplicates source reads and can exhaust physical
tuners, which was the LA outage failure mode.
- Replace the legacy fields with `relays[]`. Rejected because deployed clients and archive workers
already depend on the single-relay shape.
- Accept `relays[]` without primary legacy fields. Rejected because that would make rollback depend
on every publisher being downgraded at the same time as the directory.
- Wait for full relay racing before changing the directory. Rejected because exposing the ordered
candidate set is a small compatible step that unblocks incremental consumers.
## Rollout / teardown plan
Deploy the compatible schema first. Then add publisher fanout and consumer relay racing behind
separate flags. Teardown is removing `relays[]` from upserts and consumers; legacy primary-field
behavior remains intact throughout.