Spaces:
Paused
Paused
File size: 2,034 Bytes
0c8b3c0 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 | /**
* Rotation strategy — stateless selection logic for AccountPool.
* Strategies do not mutate input arrays or read config.
*/
import type { AccountEntry } from "./types.js";
export type RotationStrategyName = "least_used" | "round_robin" | "sticky";
export interface RotationState {
roundRobinIndex: number;
}
export interface RotationStrategy {
select(candidates: AccountEntry[], state: RotationState): AccountEntry;
}
const leastUsed: RotationStrategy = {
select(candidates) {
const sorted = [...candidates].sort((a, b) => {
const diff = a.usage.request_count - b.usage.request_count;
if (diff !== 0) return diff;
const aReset = a.usage.window_reset_at ?? Infinity;
const bReset = b.usage.window_reset_at ?? Infinity;
if (aReset !== bReset) return aReset - bReset;
const aTime = a.usage.last_used ? new Date(a.usage.last_used).getTime() : 0;
const bTime = b.usage.last_used ? new Date(b.usage.last_used).getTime() : 0;
return aTime - bTime;
});
return sorted[0];
},
};
const roundRobin: RotationStrategy = {
select(candidates, state) {
state.roundRobinIndex = state.roundRobinIndex % candidates.length;
const selected = candidates[state.roundRobinIndex];
state.roundRobinIndex++;
return selected;
},
};
const sticky: RotationStrategy = {
select(candidates) {
const sorted = [...candidates].sort((a, b) => {
const aTime = a.usage.last_used ? new Date(a.usage.last_used).getTime() : 0;
const bTime = b.usage.last_used ? new Date(b.usage.last_used).getTime() : 0;
return bTime - aTime;
});
return sorted[0];
},
};
const strategies: Record<RotationStrategyName, RotationStrategy> = {
least_used: leastUsed,
round_robin: roundRobin,
sticky,
};
export function getRotationStrategy(name: RotationStrategyName): RotationStrategy {
return strategies[name] ?? strategies.least_used;
}
/** @deprecated Use getRotationStrategy instead */
export const createRotationStrategy = getRotationStrategy;
|