docs: add relay scheduler section to architecture
Documents multi-input scheduling as a distinct concern from delivery mode. Covers strict priority, round-robin, weighted round-robin, deficit round-robin, and source suppression policies. Notes that the relay module should expose a pluggable scheduler interface. Adds scheduler policy selection to Open Questions. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -237,6 +237,26 @@ The interaction between outbound congestion and the byte budget is important: a
|
||||
|
||||
Even though the relay does not apply backpressure, it should emit **observable congestion signals** — drop counts, queue depth, byte utilization — on the control plane so that the controller can make decisions: reduce upstream quality, reroute, alert, or adjust budgets dynamically.
|
||||
|
||||
### Multi-Input Scheduling
|
||||
|
||||
When a relay has multiple input sources feeding the same output, it needs a policy for which source's frame to forward next when the link is under pressure or when frames from multiple sources are ready simultaneously. This policy is the **scheduler**.
|
||||
|
||||
The scheduler is a separate concern from delivery mode (low-latency vs completeness) — delivery mode governs buffering and drop behaviour per output; the scheduler governs which input is served when multiple compete.
|
||||
|
||||
Candidate policies (not exhaustive — the design should keep the scheduler pluggable):
|
||||
|
||||
| Policy | Behaviour |
|
||||
|---|---|
|
||||
| **Strict priority** | Always prefer the highest-priority source; lower-priority sources are only forwarded when no higher-priority frame is pending |
|
||||
| **Round-robin** | Cycle evenly across all active inputs — one frame from each in turn |
|
||||
| **Weighted round-robin** | Each input has a weight; forwarding interleaves at the given ratio (e.g. 1:3 means one frame from source A per three from source B) |
|
||||
| **Deficit round-robin** | Byte-fair rather than frame-fair variant of weighted round-robin; useful when sources have very different frame sizes |
|
||||
| **Source suppression** | A congested or degraded link simply stops forwarding from a given input entirely until conditions improve |
|
||||
|
||||
Priority remains a property of the path (set at connection time). The scheduler uses those priorities plus runtime state (queue depths, drop rates) to make per-frame decisions.
|
||||
|
||||
The `relay` module should expose a scheduler interface so policies are interchangeable without touching routing logic. Which policies to implement first is an open question — see [Open Questions](#open-questions).
|
||||
|
||||
```mermaid
|
||||
graph TD
|
||||
UP1[Upstream Source A] -->|encapsulated stream| RELAY[Relay]
|
||||
@@ -598,3 +618,4 @@ A fully-qualified node address is `site_id:namespace:instance`. Within a single
|
||||
- When a relay has multiple inputs on an encapsulated transport, how are streams tagged on the outbound side — same stream_id passthrough, or remapped?
|
||||
- What transport is used for relay edges — TCP, UDP, shared memory for local hops?
|
||||
- Should per-output byte budgets be hard limits or soft limits with hysteresis?
|
||||
- Which relay scheduler policies should be implemented first, and what is the right interface for plugging in a custom policy? Minimum viable set is probably strict priority + weighted round-robin.
|
||||
|
||||
Reference in New Issue
Block a user