• remotes: add least-connections mirror strategy (round-robin remains default) (#122)
    ci/woodpecker/tag/docker Pipeline was successful

    unkin-agent released this 2026-08-13 17:23:59 +10:00

    Why

    The mirrorlist (PR #121) always load-balances round-robin. Round-robin is oblivious to how busy each mirror is, so a slow or saturated mirror keeps getting its fair share of new requests. This adds an opt-in least-connections strategy that favors the mirror currently handling the fewest in-flight requests, steering new work toward idle mirrors. Round-robin stays the default, so existing remotes are unchanged.

    How

    • Model: models.Remote gains mirror_strategy (round_robin default/empty, or least_conn). ValidateMirrorStrategy checks the enum and requires a non-empty mirrorlist for least_conn. Empty behaves as round_robin for back-compat.
    • DB: additive mirror_strategy TEXT NOT NULL DEFAULT 'round_robin' column (CREATE TABLE + ADD COLUMN IF NOT EXISTS), wired through remoteCols/scanRemote/CreateRemote/UpdateRemote; empty normalized to round_robin on write.
    • Engine: a per-remote, per-pool-URL atomic in-flight gauge is incremented around each upstream call (head/fetch/checkUpstream). For a least_conn remote the attempt order starts with the least-loaded pool URL (ties broken by the existing round-robin rotation). Round-robin path and failover order are unchanged; single-URL pools are a no-op.
    • Tests: unit tests for least-loaded selection, round-robin default, gauge inc/dec, single-URL no-op, and validation; DB round-trip covers the new column; docker e2e adds a least_conn distribution test plus a real dnf install through a least_conn remote.

    Back-compat: unset/empty mirror_strategy is round_robin, so all existing remotes keep their current behavior.
    Reviewed-on: #122
    Co-authored-by: unkin-agent unkin-agent@unkin.net
    Co-committed-by: unkin-agent unkin-agent@unkin.net

    Downloads