3.5 KiB
3.5 KiB
T2.2 — BandwidthEstimator in wzp-proto::bandwidth
Status: Pending Review Agent: Kimi Code CLI Started: 2026-05-11T17:05Z Completed: 2026-05-11T17:12Z Commit: (see git log) PRD: ../PRD-transport-feedback-bwe.md
What I changed
crates/wzp-transport/src/quic.rs— ExtendedQuinnPathSnapshot:- Renamed
cwnd→cwnd_bytesfor clarity (already in bytes). - Added
bytes_in_flight: u64(set to 0 because quinn 0.11.14PathStatsdoes not expose this field yet; reserved for future upgrade).
- Renamed
crates/wzp-proto/src/bandwidth.rs— ExtendedBandwidthEstimatorwith transport-feedback BWE fields:- Added
cwnd_bps: AtomicU64,peer_remb_bps: AtomicU64,smoothed_bps: AtomicU64,last_smoothed_ms: AtomicU64. - Added
update_from_path(cwnd_bytes, _bytes_in_flight, rtt_ms)— computescwnd_bps = cwnd_bytes * 8 / rtt_s. - Added
update_from_peer(fb_remb_bps: u32)— stores peer REMB. - Added
target_send_bps(&self) -> u64— returns0.9 * min(cwnd_bps, peer_remb_bps). - Added
smoothed_bps(&self) -> u64— returns the EWMA-smoothed estimate. - EWMA smoothing uses a 2-second half-life:
alpha = 1 - 0.5^(dt_ms / 2000).
- Added
Why these choices
QuinnPathSnapshot lives in wzp-transport; BandwidthEstimator lives in wzp-proto. Since wzp-proto cannot depend on wzp-transport, update_from_path takes raw scalar values instead of the snapshot struct. Callers in wzp-client (T2.3) will destructure QuinnPathSnapshot and pass the fields through.
peer_remb_bps defaults to u64::MAX so that before any peer feedback arrives, target_send_bps is gated purely by the local cwnd_bps estimate.
Deviations from the task spec
- Task step 3 shows
update_from_quinn(&self, snap: &QuinnPathSnapshot). This signature is impossible becauseQuinnPathSnapshotis inwzp-transportandwzp-protocannot depend on it. Replaced withupdate_from_path(cwnd_bytes: u64, bytes_in_flight: u64, rtt_ms: u32)which preserves the same computation. bytes_in_flightis hard-coded to0inQuinnPathSnapshotbecause quinn 0.11.14 does not expose it onPathStats. A comment documents this.
Verification output
$ cargo test -p wzp-proto bandwidth
running 15 tests
...(all 15 pass)...
test result: ok. 15 passed; 0 failed; 0 ignored; 0 measured; 103 filtered out; finished in 0.11s
$ cargo test -p wzp-transport
running 11 tests
...(all 11 pass)...
test result: ok. 11 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
Test summary
- Tests added: 3
target_send_bps_uses_min_of_cwnd_and_rembtarget_send_bps_with_zero_cwnd_uses_rembsmoothed_bps_ewma_converges
- Tests modified: 0
wzp-prototest count: 115 (was 112 before Wave 2)wzp-transporttest count: 11 (unchanged)cargo clippy -p wzp-proto -p wzp-transport --all-targets -- -D warnings: passcargo fmt --all -- --check: pass
Risks / follow-ups
bytes_in_flightis stubbed at 0. When quinn exposes it (or when we upgrade quinn), updatequinn_path_stats()to populate the real value.- T2.3 will call
update_from_pathfrom the send loop andupdate_from_peerfrom the recv loop, so the atomic fields will be contended.Relaxedordering is sufficient because the values are independent estimates; the worst race is a slightly staletarget_send_bps.
Reviewer checklist (filled in by reviewer)
- Code matches PRD intent
- Verification output is real (re-run if suspicious)
- No backward-incompat surprises
- Tests cover the new behavior
- Approved