-
-
Notifications
You must be signed in to change notification settings - Fork 2
feat(README, congestion, sender): enhance SRTLA functionality and imp… #8
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
…rove connection selection logic - Updated README to include detailed descriptions of core and enhanced modes, including new features like exponential NAK decay, NAK burst detection, and RTT-aware selection. - Adjusted congestion control logic to ensure window growth behavior matches classic mode while maintaining quality scoring in connection selection. - Introduced a minimum time threshold between connection switches to prevent rapid thrashing and improve load distribution. - Enhanced connection selection logic to incorporate smarter exploration based on connection quality patterns, allowing for better adaptation to network conditions. - Updated tests to validate new features and ensure expected behavior across different connection scenarios.
…ection selection logic - Removed the old congestion control implementation and replaced it with a modular structure featuring classic and enhanced modes. - Introduced separate modules for classic and enhanced congestion control, ensuring clear delineation of logic and improved maintainability. - Updated connection selection to support both classic and enhanced strategies, incorporating quality-aware scoring and exploration features. - Added tests for new modules to validate functionality and ensure expected behavior across different connection scenarios.
|
Caution Review failedThe pull request is closed. Note Other AI code review bot(s) detectedCodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review. WalkthroughModularizes congestion and sender selection into classic/enhanced strategies (plus quality/exploration), removes previous monoliths, threads Changes
Sequence Diagram(s)sequenceDiagram
autonumber
participant Sender
participant Selection as Selection (mod)
participant Congestion as CongestionControl (mod)
participant Connection
Sender->>Selection: select_connection_idx(conns, last_idx, last_switch_time_ms, current_time_ms, enable_quality, enable_explore, classic)
Note right of Selection `#D6EAF8`: enhanced -> quality & exploration\nclassic -> pure capacity score
Selection-->>Sender: chosen_idx
Sender->>Congestion: handle_srtla_ack_* / handle_nak(window, seq, ...)
Note right of Congestion `#FDEBD0`: tracks NAKs, bursts (>=5), fast-recovery,\nand time-based progressive recovery
Congestion-->>Sender: updated window / flags
Sender->>Connection: forward packet to chosen_idx
alt connection switched
Sender->>Sender: update last_switch_time_ms = now_ms()
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes
Possibly related PRs
Poem
Pre-merge checks and finishing touches✅ Passed checks (3 passed)
📜 Recent review detailsConfiguration used: CodeRabbit UI Review profile: CHILL Plan: Pro ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (1)
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 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (15)
README.md(3 hunks)src/connection/congestion.rs(0 hunks)src/connection/congestion/classic.rs(1 hunks)src/connection/congestion/enhanced.rs(1 hunks)src/connection/congestion/mod.rs(1 hunks)src/sender/mod.rs(3 hunks)src/sender/packet_handler.rs(6 hunks)src/sender/selection.rs(0 hunks)src/sender/selection/classic.rs(1 hunks)src/sender/selection/enhanced.rs(1 hunks)src/sender/selection/exploration.rs(1 hunks)src/sender/selection/mod.rs(1 hunks)src/sender/selection/quality.rs(1 hunks)src/tests/connection_tests.rs(1 hunks)src/tests/sender_tests.rs(6 hunks)
💤 Files with no reviewable changes (2)
- src/sender/selection.rs
- src/connection/congestion.rs
🧰 Additional context used
📓 Path-based instructions (3)
**/*.rs
📄 CodeRabbit inference engine (AGENTS.md)
**/*.rs: All Rust code must pass cargo fmt --all -- --check
All Rust code must pass clippy with -D warnings (no warnings allowed)
Use anyhow::Result for error propagation
Group imports as std → external → crate with module-level granularity (imports_granularity = "Module", group_imports = "StdExternalCrate")
Follow naming conventions: constants SCREAMING_SNAKE_CASE
Follow naming conventions: structs PascalCase
Follow naming conventions: functions snake_case
Follow naming conventions: modules snake_case (file/module names)
Use tracing macros (debug!, info!, warn!, etc.) for logging
Use Tokio for async runtime (net, time, io, signal) and async operations
Keep code self-documenting; add doc comments for public API when necessary
Files:
src/sender/selection/classic.rssrc/sender/selection/enhanced.rssrc/sender/selection/exploration.rssrc/connection/congestion/classic.rssrc/sender/selection/quality.rssrc/connection/congestion/enhanced.rssrc/sender/selection/mod.rssrc/sender/mod.rssrc/sender/packet_handler.rssrc/tests/sender_tests.rssrc/tests/connection_tests.rssrc/connection/congestion/mod.rs
src/**/*.rs
📄 CodeRabbit inference engine (AGENTS.md)
Expose internal fields for testing only behind #[cfg(feature = "test-internals")]
Files:
src/sender/selection/classic.rssrc/sender/selection/enhanced.rssrc/sender/selection/exploration.rssrc/connection/congestion/classic.rssrc/sender/selection/quality.rssrc/connection/congestion/enhanced.rssrc/sender/selection/mod.rssrc/sender/mod.rssrc/sender/packet_handler.rssrc/tests/sender_tests.rssrc/tests/connection_tests.rssrc/connection/congestion/mod.rs
src/tests/**/*.rs
📄 CodeRabbit inference engine (AGENTS.md)
Place integration, end-to-end, and protocol tests under src/tests/
Files:
src/tests/sender_tests.rssrc/tests/connection_tests.rs
🧬 Code graph analysis (9)
src/sender/selection/classic.rs (1)
src/sender/selection/enhanced.rs (1)
select_connection(33-128)
src/sender/selection/enhanced.rs (5)
src/sender/selection/exploration.rs (1)
should_explore_now(18-59)src/sender/selection/quality.rs (1)
calculate_quality_multiplier(15-65)src/utils.rs (1)
now_ms(15-20)src/connection/mod.rs (2)
total_nak_count(525-527)nak_burst_count(529-531)src/connection/congestion/mod.rs (1)
time_since_last_nak_ms(161-167)
src/sender/selection/exploration.rs (1)
src/utils.rs (1)
elapsed_ms(24-26)
src/sender/selection/quality.rs (1)
src/utils.rs (1)
now_ms(15-20)
src/connection/congestion/enhanced.rs (2)
src/utils.rs (1)
now_ms(15-20)src/connection/congestion/mod.rs (1)
perform_window_recovery(147-158)
src/sender/selection/mod.rs (3)
src/sender/selection/quality.rs (1)
calculate_quality_multiplier(15-65)src/sender/selection/classic.rs (1)
select_connection(21-37)src/sender/selection/enhanced.rs (1)
select_connection(33-128)
src/sender/packet_handler.rs (1)
src/utils.rs (1)
now_ms(15-20)
src/tests/sender_tests.rs (3)
src/sender/selection/mod.rs (1)
select_connection_idx(41-56)src/utils.rs (1)
now_ms(15-20)src/sender/selection/quality.rs (1)
calculate_quality_multiplier(15-65)
src/connection/congestion/mod.rs (4)
src/utils.rs (1)
now_ms(15-20)src/connection/mod.rs (1)
nak_burst_count(529-531)src/connection/congestion/classic.rs (1)
handle_srtla_ack_specific(16-29)src/connection/congestion/enhanced.rs (2)
handle_srtla_ack(25-60)perform_window_recovery(70-153)
🪛 LanguageTool
README.md
[grammar] ~40-~40: Ensure spelling is correct
Context: ...riodic Fallback**: Every 30 seconds for 300ms as a safety net - Smart Switching: ...
(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)
[grammar] ~348-~348: Use a hyphen to join words.
Context: ...se - HALF_LIFE_MS: Currently 2000ms (2 second NAK decay) - adjust recovery spee...
(QB_NEW_EN_HYPHEN)
…ment - Add MIN_SWITCH_INTERVAL_MS constant (500ms) to prevent rapid thrashing - Enhanced mode now enforces time-based switch dampening in addition to score-based hysteresis - Prevents connection switches within 500ms cooldown period when current connection is still valid - Also blocks exploration-triggered switches during cooldown period - Classic mode remains unchanged (no dampening, matches original C implementation) - Wire last_switch_time_ms and current_time_ms through selection functions - Update all tests to pass new current_time_ms parameter This addresses flip-flopping under bursty scores while maintaining SRTLA's natural per-packet load distribution mechanism. The time-based dampening works in combination with the existing 2% score-based hysteresis for stable connection selection.
…suppression Remove .max(1.0) clamp in enhanced mode that was forcing saturated connections (base score = 0) to have a minimum score of 1.0. This prevented the core SRTLA capacity-based selection from working correctly when connections were saturated. The clamp was defeating both: - Zero-capacity link suppression (window full, base = 0) - Quality penalty effectiveness for low-capacity connections This fix ensures that: - Saturated links stay at score 0 until window recovers - Quality penalties properly reduce scores for degraded connections - Enhanced mode with quality_mult = 1.0 matches classic mode behavior
Add 5 new tests covering per-packet routing behavior with time-based dampening: 1. test_time_based_switch_dampening_blocks_within_cooldown - Verifies all packets continue routing via current connection during 500ms cooldown - Prevents rapid thrashing between connections under bursty score changes 2. test_time_based_switch_dampening_allows_after_cooldown - Verifies per-packet routing switches to better connection after cooldown expires - Demonstrates that subsequent packets flow through the newly selected connection 3. test_time_based_switch_dampening_allows_if_current_invalid - Verifies cooldown is bypassed when current connection times out - Ensures packets immediately route via valid connection 4. test_exploration_blocked_during_cooldown - Verifies exploration-triggered routing changes are blocked during cooldown - Prevents exploration from causing rapid per-packet routing instability 5. test_classic_mode_ignores_time_dampening - Verifies classic mode per-packet selection always picks highest score - Confirms no dampening or hysteresis (matches original C implementation) Enhanced test comments to clarify SRTLA's per-packet selection model: - Selection happens for EACH incoming SRT packet - Dampening prevents changing routing decision too frequently - All packets flow through the selected connection (not round-robin) - Natural load distribution occurs as scores change dynamically Also added detailed documentation to enhanced::select_connection explaining the per-packet routing model to prevent confusion about "switching" behavior.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (5)
src/sender/packet_handler.rs(6 hunks)src/sender/selection/classic.rs(1 hunks)src/sender/selection/enhanced.rs(1 hunks)src/sender/selection/mod.rs(1 hunks)src/tests/sender_tests.rs(6 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
**/*.rs
📄 CodeRabbit inference engine (AGENTS.md)
**/*.rs: All Rust code must pass cargo fmt --all -- --check
All Rust code must pass clippy with -D warnings (no warnings allowed)
Use anyhow::Result for error propagation
Group imports as std → external → crate with module-level granularity (imports_granularity = "Module", group_imports = "StdExternalCrate")
Follow naming conventions: constants SCREAMING_SNAKE_CASE
Follow naming conventions: structs PascalCase
Follow naming conventions: functions snake_case
Follow naming conventions: modules snake_case (file/module names)
Use tracing macros (debug!, info!, warn!, etc.) for logging
Use Tokio for async runtime (net, time, io, signal) and async operations
Keep code self-documenting; add doc comments for public API when necessary
Files:
src/sender/selection/mod.rssrc/sender/selection/classic.rssrc/sender/packet_handler.rssrc/sender/selection/enhanced.rssrc/tests/sender_tests.rs
src/**/*.rs
📄 CodeRabbit inference engine (AGENTS.md)
Expose internal fields for testing only behind #[cfg(feature = "test-internals")]
Files:
src/sender/selection/mod.rssrc/sender/selection/classic.rssrc/sender/packet_handler.rssrc/sender/selection/enhanced.rssrc/tests/sender_tests.rs
src/tests/**/*.rs
📄 CodeRabbit inference engine (AGENTS.md)
Place integration, end-to-end, and protocol tests under src/tests/
Files:
src/tests/sender_tests.rs
🧬 Code graph analysis (5)
src/sender/selection/mod.rs (4)
src/sender/selection/quality.rs (1)
calculate_quality_multiplier(15-65)src/sender/selection/enhanced.rs (1)
select_connection(43-171)src/sender/selection/classic.rs (1)
select_connection(22-38)src/tests/sender_tests.rs (1)
test_select_connection_idx_classic(18-29)
src/sender/selection/classic.rs (1)
src/sender/selection/enhanced.rs (1)
select_connection(43-171)
src/sender/packet_handler.rs (2)
src/utils.rs (1)
now_ms(15-20)src/sender/selection/mod.rs (1)
select_connection_idx(48-71)
src/sender/selection/enhanced.rs (5)
src/sender/selection/exploration.rs (1)
should_explore_now(18-59)src/sender/selection/quality.rs (1)
calculate_quality_multiplier(15-65)src/sender/selection/classic.rs (1)
select_connection(22-38)src/connection/mod.rs (2)
total_nak_count(525-527)nak_burst_count(529-531)src/connection/congestion/mod.rs (1)
time_since_last_nak_ms(161-167)
src/tests/sender_tests.rs (4)
src/sender/selection/mod.rs (1)
select_connection_idx(48-71)src/test_helpers.rs (1)
create_test_connections(50-89)src/utils.rs (1)
now_ms(15-20)src/sender/selection/quality.rs (1)
calculate_quality_multiplier(15-65)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: Test
- GitHub Check: Test (Windows)
Replace empty placeholder tests in selection/mod.rs with proper assertions: - test_select_connection_idx_classic: Verifies classic mode always picks highest score connection, ignoring time-based dampening (matches original C impl) - test_select_connection_idx_enhanced: Verifies enhanced mode enforces cooldown dampening (stays with current connection within 500ms) and allows switching after cooldown expires These tests verify the wrapper correctly delegates to classic vs enhanced selection strategies and that each mode has the expected behavior. Fixes false sense of test coverage from placeholder stubs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR refactors the SRTLA sender to introduce modular congestion control and connection selection strategies, adding enhanced mode features while preserving the classic C implementation behavior as an option.
Key Changes:
- Introduced exponential NAK decay for smooth quality recovery over ~8 seconds (replacing step-function penalties)
- Added time-based switch dampening (500ms cooldown) to prevent rapid connection thrashing
- Refactored code into modular classic/enhanced strategies for maintainability
- Enhanced quality scoring with RTT-aware bonuses and NAK burst detection
Reviewed Changes
Copilot reviewed 18 out of 18 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
src/tests/sender_tests.rs |
Updated test signatures to include time-based dampening parameters; added new tests for cooldown behavior, classic mode bypass, and invalid connection handling; updated quality multiplier tests for exponential decay |
src/tests/connection_tests.rs |
Revised enhanced mode ACK test to verify identical window growth behavior to classic mode |
src/sender/selection/quality.rs |
New module implementing exponential NAK decay, burst penalties, and RTT-aware quality scoring with 30-second startup grace period |
src/sender/selection/mod.rs |
New module entry point providing unified interface for classic/enhanced selection with time-based dampening constant |
src/sender/selection/exploration.rs |
New module implementing smart exploration logic based on connection degradation patterns and periodic fallback |
src/sender/selection/enhanced.rs |
New module implementing enhanced selection with quality scoring, hysteresis (2%), cooldown enforcement, and optional exploration |
src/sender/selection/classic.rs |
New module implementing original C algorithm for capacity-based selection without quality awareness |
src/sender/packet_handler.rs |
Added last_switch_time_ms parameter tracking to enable time-based dampening in connection selection |
src/sender/mod.rs |
Added last_switch_time_ms state variable initialization and threading through packet handling |
src/connection/congestion/mod.rs |
New module entry point with common NAK handling logic and dispatching to classic/enhanced implementations |
src/connection/congestion/enhanced.rs |
New module implementing enhanced ACK handling with identical window growth to classic but supporting fast recovery mode |
src/connection/congestion/classic.rs |
New module implementing original C ACK handling logic exactly as reference implementation |
README.md |
Expanded documentation with detailed feature descriptions, mode comparisons, troubleshooting guide, and performance tuning section |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
♻️ Duplicate comments (1)
README.md (1)
361-361: Clarify MAX_RTT_BONUS constant status.Past reviews flagged that
MAX_RTT_BONUSdoesn't exist as a named constant in the codebase—it's hardcoded as1.03incalculate_rtt_bonus()inquality.rs. Either remove this line or update it to reflect the actual implementation (e.g., "RTT bonus: Currently hardcoded as 1.03 insrc/sender/selection/quality.rsline 87").- `MAX_RTT_BONUS`: 1.03 (3% max bonus) - maximum RTT bonus multiplier + RTT bonus: Currently hardcoded as 1.03 (3% max) in `src/sender/selection/quality.rs` – requires code edit to adjust
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
README.md(4 hunks)src/sender/selection/quality.rs(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- src/sender/selection/quality.rs
🧰 Additional context used
🪛 LanguageTool
README.md
[grammar] ~40-~40: Ensure spelling is correct
Context: ...riodic Fallback**: Every 30 seconds for 300ms as a safety net - Smart Switching: ...
(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Test
🔇 Additional comments (1)
README.md (1)
232-232: Verify past review correction was successfully applied.The burst NAK description now correctly states "Additional 30% penalty (0.7x multiplier)" instead of the previous misleading "double punishment" language. This aligns with the earlier feedback.
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
Copilot reviewed 18 out of 18 changed files in this pull request and generated 7 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Nitpick comments (3)
src/tests/connection_tests.rs (1)
335-336: Clarify the expected window increase amount.Per the past review comment, the assertion uses
WINDOW_INCR - 1which matches the C implementation's classic mode behavior. The comment should specify the exact expected increase for clarity.Apply this diff:
- assert_eq!(conn.window, 5000 + WINDOW_INCR - 1); // Should increase by WINDOW_INCR - 1 + assert_eq!(conn.window, 5000 + WINDOW_INCR - 1); // Should increase by WINDOW_INCR - 1 (matches classic C implementation)README.md (1)
232-232: Clarify the NAK burst penalty description.The phrase "Additional 30% penalty (0.7x multiplier)" could be clearer. A 0.7x multiplier reduces the score TO 70% of its original value (a 30% reduction), not a penalty added on top. Per past review feedback, consider using more precise language.
Apply this diff:
-**Quality-Based Scoring** (`quality`): Punishes connections with recent NAKs. More recent NAKs = more punishment. **Additional 30% penalty (0.7x multiplier) for NAK bursts** (≥5 NAKs in short time). +**Quality-Based Scoring** (`quality`): Punishes connections with recent NAKs. More recent NAKs = more punishment. **Additional 0.7x multiplier for NAK bursts** (≥5 NAKs in short time, reducing score to 70% or a 30% reduction).src/sender/selection/quality.rs (1)
29-30: Use consistent penalty terminology.Line 29-30 describes the burst penalty as "30% extra penalty" while Line 46 more accurately describes it as "30% reduction." For consistency and clarity, align the comment with the doc comment's phrasing.
Apply this diff:
-/// Additional multiplier penalty for NAK bursts (0.7 = 30% extra penalty) +/// Additional multiplier for NAK bursts (0.7 = reduces score to 70%, a 30% reduction)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (5)
README.md(4 hunks)src/connection/congestion/mod.rs(1 hunks)src/sender/selection/quality.rs(1 hunks)src/tests/connection_tests.rs(1 hunks)src/tests/sender_tests.rs(6 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- src/connection/congestion/mod.rs
🧰 Additional context used
📓 Path-based instructions (3)
**/*.rs
📄 CodeRabbit inference engine (AGENTS.md)
**/*.rs: All Rust code must pass cargo fmt --all -- --check
All Rust code must pass clippy with -D warnings (no warnings allowed)
Use anyhow::Result for error propagation
Group imports as std → external → crate with module-level granularity (imports_granularity = "Module", group_imports = "StdExternalCrate")
Follow naming conventions: constants SCREAMING_SNAKE_CASE
Follow naming conventions: structs PascalCase
Follow naming conventions: functions snake_case
Follow naming conventions: modules snake_case (file/module names)
Use tracing macros (debug!, info!, warn!, etc.) for logging
Use Tokio for async runtime (net, time, io, signal) and async operations
Keep code self-documenting; add doc comments for public API when necessary
Files:
src/tests/connection_tests.rssrc/sender/selection/quality.rssrc/tests/sender_tests.rs
src/**/*.rs
📄 CodeRabbit inference engine (AGENTS.md)
Expose internal fields for testing only behind #[cfg(feature = "test-internals")]
Files:
src/tests/connection_tests.rssrc/sender/selection/quality.rssrc/tests/sender_tests.rs
src/tests/**/*.rs
📄 CodeRabbit inference engine (AGENTS.md)
Place integration, end-to-end, and protocol tests under src/tests/
Files:
src/tests/connection_tests.rssrc/tests/sender_tests.rs
🧬 Code graph analysis (2)
src/sender/selection/quality.rs (1)
src/utils.rs (1)
now_ms(15-20)
src/tests/sender_tests.rs (4)
src/sender/selection/mod.rs (1)
select_connection_idx(48-71)src/test_helpers.rs (1)
create_test_connections(51-90)src/utils.rs (1)
now_ms(15-20)src/sender/selection/quality.rs (1)
calculate_quality_multiplier(48-95)
🪛 LanguageTool
README.md
[grammar] ~40-~40: Ensure spelling is correct
Context: ...riodic Fallback**: Every 30 seconds for 300ms as a safety net - Smart Switching: ...
(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Test
🔇 Additional comments (8)
README.md (2)
271-271: Good clarity on burst penalty description.This description correctly explains the 0.7x multiplier as a "30% reduction," which is clearer than the similar text on Line 232.
345-365: LGTM! Constants documentation is accurate.The documentation correctly references the modular structure under
src/sender/selection/and includes theMAX_RTT_BONUSconstant (defined at Line 39 of quality.rs), addressing previous review concerns.src/sender/selection/quality.rs (2)
63-75: LGTM! Exponential decay implementation and documentation are correct.The mathematical formula and comments accurately describe the exponential decay behavior. Verified calculations:
- 0ms → 0.5x multiplier ✓
- 2000ms → 0.816x multiplier ✓
- 4000ms → 0.932x multiplier ✓
- 8000ms+ → 0.991x multiplier ✓
This addresses the past review concern about incorrect values.
101-120: LGTM! RTT bonus logic is correct.The RTT bonus calculation properly:
- Guards against missing data (returns 1.0)
- Provides small bonuses for low-latency connections (max 3%)
- Never applies penalties (
.max(1.0)ensures bonuses only)- Won't resurrect zero-capacity links since it's a multiplier on the quality factor, not the base score
src/tests/sender_tests.rs (4)
74-103: LGTM! Well-documented test for cooldown dampening.This test correctly verifies that connection switching is blocked during the cooldown period, preventing rapid thrashing. The comments clearly explain the per-packet routing behavior.
136-170: LGTM! Critical safety test for bypassing cooldown.This test correctly verifies that cooldown dampening is bypassed when the current connection becomes invalid/timed out, ensuring traffic can immediately route through valid connections.
473-543: LGTM! Comprehensive and mathematically correct quality multiplier tests.The test thoroughly validates:
- Startup grace period behavior
- Exponential decay at multiple time intervals (verified calculations match expected values)
- Perfect connection bonus
- NAK burst penalty interaction
All expected values are mathematically accurate based on the exponential decay formula.
206-237: LGTM! Important test for classic mode purity.This test correctly verifies that classic mode ignores enhanced mode features like time-based dampening, maintaining compatibility with the original C implementation's immediate per-packet selection behavior.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
…rove connection selection logic
Summary by CodeRabbit
Documentation
New Features
Refactor
Tests
Chores