classic: per-link weights (Moblin connection priorities) via the IPs file - #24
Conversation
…priorities) Each IPs-file line is `<ip>[ <weight>]`: integer 1..10, missing = 1, larger values clamped to 10, a 0 or unparsable weight is warned about and read as 1 (the IP still counts, so the SIGHUP reload guard is unchanged). Weights are normalised on every load so the lowest link is 1 (priority - lowest + 1, as Moblin's updateConnectionPriorities). Classic selection multiplies get_score() by the link's weight while its window is above 20 000, fades the multiplier linearly to 1 between 20 000 and 10 000, and ignores it below (Moblin's RemoteConnection.score()). A weight of 1 is exactly neutral, so an unweighted file schedules as before. get_score() and enhanced mode are untouched. Observability: srtla_send_link_weight gauge per link, weight in the stats topic, in the 'added uplink' line, on reload re-weights and in the SIGHUP queued line. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
|
Navigate logical layers of code changes, visualize relationships, and explore their blast radius. Note Repository guideline files applied to this review (2)No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository: irlserver/srtla_send/.coderabbit.yaml Review profile: CHILL Plan: Advanced Run ID: 📒 Files selected for processing (12)
Included review availability: This review used your included allowance. Your plan provides up to 1 included review per hour; 0 remain after this review. 📝 WalkthroughWalkthrough
ChangesWeighted link selection
Priority: ⬇️ Low Estimated code review effort: 3 (Moderate) | ~25 minutes Change: Feature Sequence Diagram(s)sequenceDiagram
participant IpFile as BIND_IPS_FILE
participant Sender as Sender
participant Connections as Connection manager
participant Selector as Classic selection
IpFile->>Sender: provide IP entries and optional weights
Sender->>Connections: pass parsed IPs and normalized weights
Connections->>Connections: assign weights to existing and new links
Selector->>Connections: read link scores and weights
Suggested reviewers: Merge Risk: ⚪ Minimal · up to No actionable merge-blocking issue is established for the weighted-link behavior. The change is mergeable subject to normal build and test checks. Security Architecture ReviewSecurity architecture risk: 🔵 Low · up to The preferences are bounded and do not override link eligibility or grant additional authority. No introduced security weakness was established. Live reload retains existing partial-failure behavior, while configuration permissions and recovery after external process interruption remain unverified. Retained concerns Security review detailsSecurity Blast Radius
Trust Boundaries and Controls
Resilience and Maintainability Implications
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
|
Autopilot could not be updated. Open Coding to check access and billing. |
Why
On a bonded setup the links rarely cost the same: free venue Wi-Fi or Ethernet next to a metered phone tether. Classic mode balances purely on capacity (
window / (in_flight + 1)), so an expensive link carries traffic even when the cheap one has room. This PR lets the user say "prefer this link": the preferred link carries what it can while it is healthy, and the others take over as it congests or dies, exactly as they do today.It is a copy of Moblin's "connection priorities", the only open per-packet bonding scheduler with priorities we could find (BELABOX srtla and belaUI have none), so it behaves the same as what users already know from Moblin.
Semantics (as Moblin)
w - lowest + 1(it subtracts, it does not divide), as inSrtlaClient.swiftupdateConnectionPriorities.get_score()is multiplied by the weight while its window is above 20 000; between 20 000 and 10 000 the multiplier fades linearly from the weight to 1; at or below 10 000 it is 1. This isRemoteConnection.swiftscore(). The thresholds carry over 1:1 becauseWINDOW_DEF/WINDOW_MAX/WINDOW_MULTare the same constants.How to use it
The weight goes in the IPs file, one link per line:
That is the file the sender already reloads on
SIGHUP, so weights are hot-reloadable with no new flag or RPC. Rules:0or an unparsable weight is logged as a warning and read as 1. The IP still counts, so the reload guard behaves as before.Scope
get_score()itself is unchanged, and enhanced mode ignores weights (a test covers this).Observability
srtla_send_link_weight{ip=…}.added uplink … (weight N)line, and in the reload /SIGHUPlog lines.Tests
14 new tests in
src/tests/link_weight_tests.rs:cargo +nightly test --workspacepasses (549 tests), andcargo +nightly fmt --checkandclippy --all-targets -D warningsare clean on this branch (rebased ontoc86a3e1; the only conflict was thesrc/tests/mod.rsmodule list).Bench evidence
Two-uplink LAN bench: Ethernet
en7+ Wi-Fien0, a 1080p30 file source through an adaptive encoder, v4.1.0 + this patch, classic mode, receiver irlserver/srtla7fa6985.Link A capped to ~1.7 Mbit/s for 60 s, B uncapped (preferred A = weight 10, other link 1). B's share of the bytes:
Traffic spilled to B within 0.9 s of the cap and came back to A 4.7 s after it ended (5.5 s with weights 1/1). No stream damage in either mode.
Preferred link unplugged 2 / 8 / 12 / 8 s, then the other link for 8 s: hitless with and without weights. There was no SRT session END and no corrupt packets, and the survivor carried 5.1–7.2 Mbit/s.
Both links capped below the stream: it still aggregates with weights on, splitting 49.5 % / 50.5 % for 600 s with no damage.
On this Ethernet+Wi-Fi bench, classic mode already sends most traffic to the wired link. With a real metered tether, the idle trickle on the expensive link is where the saving shows up.
🤖 Generated with Claude Code
Summary by CodeRabbit