mirror of
https://github.com/Nezumi-2711/9router.git
synced 2026-09-22 20:00:47 +00:00
feat: add sticky round-robin routing strategy
Implements a "sticky" round-robin strategy that uses the same provider account for a configurable number of consecutive calls (default 3) before switching to the next one. This optimizes for prompt caching by reducing organization/account rotation. Adds a configuration input to the Profile settings page. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
committed by
decolua
co-authored by
Claude Sonnet 4.5
parent
f2abcc6585
commit
4f292aae63
+37
-10
@@ -33,17 +33,44 @@ export async function getProviderCredentials(provider, excludeConnectionId = nul
|
||||
|
||||
let connection;
|
||||
if (strategy === "round-robin") {
|
||||
// Sort by lastUsed (nulls first) to pick the least recently used
|
||||
const sorted = [...availableConnections].sort((a, b) => {
|
||||
if (!a.lastUsedAt && !b.lastUsedAt) return (a.priority || 999) - (b.priority || 999);
|
||||
if (!a.lastUsedAt) return -1;
|
||||
if (!b.lastUsedAt) return 1;
|
||||
return new Date(a.lastUsedAt) - new Date(b.lastUsedAt);
|
||||
});
|
||||
connection = sorted[0];
|
||||
const stickyLimit = settings.stickyRoundRobinLimit || 3;
|
||||
|
||||
// Update lastUsedAt asynchronously
|
||||
updateProviderConnection(connection.id, { lastUsedAt: new Date().toISOString() }).catch(() => {});
|
||||
// Sort by lastUsed (most recent first) to find current candidate
|
||||
const byRecency = [...availableConnections].sort((a, b) => {
|
||||
if (!a.lastUsedAt && !b.lastUsedAt) return (a.priority || 999) - (b.priority || 999);
|
||||
if (!a.lastUsedAt) return 1;
|
||||
if (!b.lastUsedAt) return -1;
|
||||
return new Date(b.lastUsedAt) - new Date(a.lastUsedAt);
|
||||
});
|
||||
|
||||
const current = byRecency[0];
|
||||
const currentCount = current?.consecutiveUseCount || 0;
|
||||
|
||||
if (current && current.lastUsedAt && currentCount < stickyLimit) {
|
||||
// Stay with current account
|
||||
connection = current;
|
||||
// Update lastUsedAt and increment count
|
||||
updateProviderConnection(connection.id, {
|
||||
lastUsedAt: new Date().toISOString(),
|
||||
consecutiveUseCount: (connection.consecutiveUseCount || 0) + 1
|
||||
}).catch(() => {});
|
||||
} else {
|
||||
// Pick the least recently used (excluding current if possible)
|
||||
const sortedByOldest = [...availableConnections].sort((a, b) => {
|
||||
if (!a.lastUsedAt && !b.lastUsedAt) return (a.priority || 999) - (b.priority || 999);
|
||||
if (!a.lastUsedAt) return -1;
|
||||
if (!b.lastUsedAt) return 1;
|
||||
return new Date(a.lastUsedAt) - new Date(b.lastUsedAt);
|
||||
});
|
||||
|
||||
connection = sortedByOldest[0];
|
||||
|
||||
// Update lastUsedAt and reset count to 1
|
||||
updateProviderConnection(connection.id, {
|
||||
lastUsedAt: new Date().toISOString(),
|
||||
consecutiveUseCount: 1
|
||||
}).catch(() => {});
|
||||
}
|
||||
} else {
|
||||
// Default: fill-first (already sorted by priority in getProviderConnections)
|
||||
connection = availableConnections[0];
|
||||
|
||||
Reference in New Issue
Block a user