Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 47 additions & 0 deletions pkg/router/policy/preset/preset_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,53 @@ func TestEngine_OnTick_AdaptiveEvictsLowThroughputLeg(t *testing.T) {
}
}

// TestEngine_OnTick_AdaptiveCapsActiveUnderLoad asserts the active set is capped
// at adaptCap even when the group reads SATURATED. During the uncap fill, legs
// are born active and route-setup traffic keeps the group saturated — the park
// must still cap active at adaptCap (parking the slowest excess) so the reorder
// buffer never spans more than adaptCap legs; only born-active excess is shed,
// never below adaptCap under load.
func TestEngine_OnTick_AdaptiveCapsActiveUnderLoad(t *testing.T) {
e := seedSaturatedAdaptive(1)
const n = 20
legs := make([]LegInfo, n)
for i := range legs {
tid := string(rune('a' + i))
var recv uint64
if i == 0 {
tid = "t0" // matches seedSaturatedAdaptive's prevRecv key
recv = 1_000_000 // fresh delta keeps the group saturated this tick
}
// distinct latencies: leg i = 20+i*10 ms, so higher index = slower.
legs[i] = LegInfo{Index: i, TransportID: tid, Kind: "stcpr", LatencyMs: 20 + i*10, Alive: true, RecvBytes: recv}
}
act := e.OnTick("adaptive", legs)
wantParked := n - adaptCap
if len(act.DemoteToStandby) != wantParked {
t.Fatalf("under load, active must be capped at adaptCap=%d: want %d parked, got %d: %+v",
adaptCap, wantParked, len(act.DemoteToStandby), act)
}
parked := map[int]bool{}
for _, idx := range act.DemoteToStandby {
if idx == 0 {
t.Fatalf("must never park leg 0; got %+v", act.DemoteToStandby)
}
parked[idx] = true
}
// The adaptCap kept-active legs are the fastest (leg 0 + legs 1..adaptCap-1);
// the n-adaptCap slowest (highest index) are parked.
for i := adaptCap; i < n; i++ {
if !parked[i] {
t.Errorf("slowest excess legs must be parked to cap active at adaptCap: leg %d (%dms) not parked", i, 20+i*10)
}
}
for i := 1; i < adaptCap; i++ {
if parked[i] {
t.Errorf("fastest legs must stay active under load: leg %d (%dms) was parked", i, 20+i*10)
}
}
}

func TestDecide_TimeOfDay(t *testing.T) {
const h = int64(3600) * 1_000_000_000
if got := Decide("time-of-day", Context{NowUnixNano: 11 * h}, nil); got.Mux != 1 {
Expand Down
23 changes: 21 additions & 2 deletions pkg/router/policy/preset/tick.go
Original file line number Diff line number Diff line change
Expand Up @@ -970,7 +970,26 @@ func (e *Engine) tickAdaptive(legs []LegInfo) RotationAction {
// Cooldown is set after a bulk park so the freshly-lean set settles before
// any optimization reshape; drop-recovery (1) and unhealthy-evict (2) still
// bypass it, so safety is preserved.
if !saturated && !fwdSaturated && aliveCount > desiredActive && standbyCount < adaptStandbyMax && newestAliveIdx > 0 {
//
// PARK FLOOR — the active width we converge DOWN to this tick:
// - idle (not saturated): desiredActive, the lean steady target, so an
// interactive/idle flow settles onto the fastest few legs.
// - under load (saturated): adaptCap — the MAXIMUM the saturation-growth
// rule (4) would ever build. This is the fix for the uncap fill: legs are
// born ACTIVE (self-heal filling the 512-deep reserve), and while the pool
// fills, the route-setup/keepalive traffic reads as "saturated" — so a
// park gated on !saturated stayed suppressed and aliveCount ballooned to
// dozens of active legs (HoL-stalling the no-skip reorder buffer) even
// though rule 4 would never grow the active set beyond adaptCap. So the
// park ALWAYS caps active at adaptCap, and only trims below it (to
// desiredActive) when genuinely idle. Under a real bulk download active is
// already at adaptCap, so this only sheds born-active excess, never the
// legs the download is using.
parkFloor := desiredActive
if (saturated || fwdSaturated) && parkFloor < adaptCap {
parkFloor = adaptCap
}
if aliveCount > parkFloor && standbyCount < adaptStandbyMax && newestAliveIdx > 0 {
// Rank active non-leg-0 legs by smoothed latency, slowest first. Use the
// EWMA where we have it, else the raw sample; an unmeasured leg sorts as
// slowest (parked first) so unknowns don't linger in the active set.
Expand All @@ -993,7 +1012,7 @@ func (e *Engine) tickAdaptive(legs []LegInfo) RotationAction {
act = append(act, actLeg{l.Index, lat})
}
sort.Slice(act, func(i, j int) bool { return act[i].lat > act[j].lat })
surplus := aliveCount - desiredActive
surplus := aliveCount - parkFloor
if room := adaptStandbyMax - standbyCount; surplus > room {
surplus = room
}
Expand Down
Binary file modified pkg/router/policy/wasm/presets/bundle.wasm
Binary file not shown.
Loading