• proxy: snapshot in-flight counts before sorting (least_conn selection O(n)) (#124)
    ci/woodpecker/tag/docker Pipeline was successful

    unkin-agent released this 2026-08-13 19:55:21 +10:00

    Why

    least_conn mirror selection (baseURLAttemptOrder) scaled super-linearly. After rotating the pool by the round-robin cursor it sort.SliceStabled with a comparator that called inflightCounter on every comparison — and each call did a remoteName+"\x00"+url concat plus a sync.Map LoadOrStore with a speculative new(atomic.Int64). So each selection cost O(n·log n) map lookups + allocations, all on the cache-miss/upstream path.

    How

    Snapshot each mirror's in-flight count once, then sort the snapshot — O(n) map loads, zero comparator allocations.

    • Add read-only inflightCount(name, url) int64: plain sync.Map Load, returns 0 when the gauge is absent (no LoadOrStore, no speculative allocation).
    • least_conn branch builds a {url, count} snapshot via one inflightCount per rotated URL, sort.SliceStable by count ascending, then extracts the URLs.
    • beginAttempt/endAttempt keep the create-on-write inflightCounter path — they legitimately need to create the gauge.

    Numbers (BenchmarkBaseURLAttemptOrder_LeastConn, Ryzen 7 4700U, best of 3)

    pool before ns/op after ns/op before allocs after allocs before B/op after B/op
    3 ~2516 ~1492 22 8 474 296
    8 ~14647 ~3319 131–132 8 2688 568

    Allocs are now constant regardless of pool size; pool-8 is ~4.8x faster with ~16x fewer allocations.

    Behavior

    Unchanged: least-loaded first, RR rotation as the stable tie-break, round_robin and single-URL paths untouched. Pure internal optimization — no API/schema/DB change. Added a multi-mirror tie-break test asserting all-equal load yields the RR rotation; make test (-race) green, vet/fmt clean.
    Reviewed-on: #124
    Co-authored-by: unkin-agent unkin-agent@unkin.net
    Co-committed-by: unkin-agent unkin-agent@unkin.net

    Downloads