SIGN IN SIGN UP

feat: add strict ranking mode to session-drain-soonest strategy

The session-drain-soonest holder choice picks the account with the most
recent session_start among all active 5h sessions and never preempts it,
while session_start is written by paths that carry no drain intent (any
served request opening a session, the usage-poller rollover callback,
keepalive and auto-refresh probes). The drain comparator therefore only
orders the failover tail.

With several concurrently active sessions — the production-normal state —
whichever account last received a session_start write holds ALL traffic:
a 5.5h production trace showed 3570/3570 events tail-sorted correctly but
zero drain decisions at position 0; the earliest-reset account was ranked
first in every decision and received 12% of traffic while the
latest-reset account received 35%, so expiring weekly quota goes unused.

Now an additive strict mode (new StrategyName session-drain-soonest-strict,
same class with a mode parameter; the default remains byte-identical)
ranks every AVAILABLE account with one canonical comparator: earliest
future weekly reset, then active-session status as the tie-break, then
priority, utilization, and account id as a determinism anchor. The
drain-earliest account keeps winning even after its own 5h window ages
out (it gets a fresh session on selection); with all weekly resets
unknown (cold usage cache after a restart) the incumbent active account
keeps the traffic instead of utilization-ranked spraying; the
auto-fallback exception still forces position 0 in both modes, with its
tail following the mode's comparator so the failover loop always walks
one consistent order.

Considered changing the existing mode's behaviour in place — rejected
because the never-preempted rule is documented intent pinned by tests;
also considered moving the model-capacity filter ahead of the strategy —
rejected as redundant, since the post-strategy filter already promotes
the drain-next candidate and inheriting the crown is inert under strict
ranking.
M
Matthias Breddin committed
0cfc9d43a5080f0a851cfbb9da57d855b06c201b
Parent: 0b915d4