package limiter_test // v2.3 task 02: Track counts a request without holding or refusing it. A route with queue = false // leaves queueing to llama-server's own slots, but its requests are still load on the host, so the // routes that do queue must see them. import ( "context" "testing" "time" "git.wntrmute.dev/kyle/crossbar/internal/limiter" ) func TestTrackNeverWaitsAndCounts(t *testing.T) { l := limiter.New() l.Configure("alpha", "m", 1, 0) // one slot, no waiting room start := time.Now() rel1 := l.Track("alpha", "m") rel2 := l.Track("alpha", "m") rel3 := l.Track("alpha", "m") if d := time.Since(start); d > 50*time.Millisecond { t.Fatalf("Track waited %v", d) } if n := l.InFlight("alpha", "m"); n != 3 { t.Fatalf("in flight = %d, want 3 (Track may pass parallel)", n) } if n := l.FreeSlots("alpha"); n != 0 { t.Errorf("free slots = %d, want 0", n) } // A queueing request sees the host full: no waiting room, so it is refused. if _, _, err := l.Acquire(context.Background(), "alpha", "m"); err == nil { t.Error("Acquire on an over-tracked pair succeeded; want ErrQueueFull") } rel1() rel1() // idempotent rel2() rel3() if n := l.InFlight("alpha", "m"); n != 0 { t.Errorf("in flight after release = %d, want 0", n) } } // A waiter gets a slot only once in flight is back under parallel: releasing a tracked request // while the pair is still over its limit must not hand the slot on. func TestTrackReleaseHandsOverOnlyUnderTheLimit(t *testing.T) { l := limiter.New() l.Configure("alpha", "m", 1, 1) relA := l.Track("alpha", "m") relB := l.Track("alpha", "m") // in flight 2, parallel 1 got := make(chan func(), 1) go func() { rel, _, err := l.Acquire(context.Background(), "alpha", "m") if err != nil { t.Error(err) close(got) return } got <- rel }() waitUntil(t, func() bool { return l.Queued("alpha", "m") == 1 }) relA() // in flight 1 == parallel: still no free slot select { case <-got: t.Fatal("waiter got a slot while in flight was still at parallel") case <-time.After(100 * time.Millisecond): } if n := l.InFlight("alpha", "m"); n != 1 { t.Fatalf("in flight = %d after one release, want 1", n) } relB() // now the slot is free: hand it to the waiter select { case rel := <-got: if rel == nil { t.Fatal("waiter failed") } if n := l.InFlight("alpha", "m"); n != 1 { t.Errorf("in flight = %d with the waiter running, want 1", n) } rel() case <-time.After(2 * time.Second): t.Fatal("waiter never got the freed slot") } if n := l.InFlight("alpha", "m"); n != 0 { t.Errorf("in flight at the end = %d, want 0", n) } }