Fix Debrid-Link key selection: always use first available key

Replace shared currentKeyIndex round-robin with sequential scan from
first key. All parallel items now consistently use the same key (e.g.
Key 3) until it hits a quota/error, then all move to Key 4, etc.

Previously, currentKeyIndex was shared across parallel unrestrict calls,
causing items to scatter across keys (3, 5, 7) even when Key 3 still
had capacity.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Sucukdeluxe 2026-03-07 19:33:40 +01:00
parent fef9ff6318
commit afbd425227

View File

@ -1461,7 +1461,6 @@ export async function fetchDebridLinkHostLimits(apiKeysRaw: string, host = "rapi
class DebridLinkClient { class DebridLinkClient {
private apiKeys: ReturnType<typeof parseDebridLinkApiKeys>; private apiKeys: ReturnType<typeof parseDebridLinkApiKeys>;
private currentKeyIndex: number = 0;
public constructor(apiKeysRaw: string) { public constructor(apiKeysRaw: string) {
this.apiKeys = parseDebridLinkApiKeys(apiKeysRaw); this.apiKeys = parseDebridLinkApiKeys(apiKeysRaw);
@ -1476,25 +1475,22 @@ class DebridLinkClient {
throw new Error("Debrid-Link: Kein aktiver API-Key verfuegbar (deaktiviert oder am Tageslimit)"); throw new Error("Debrid-Link: Kein aktiver API-Key verfuegbar (deaktiviert oder am Tageslimit)");
} }
let checkedKeys = 0; // Always start from first key — use first available, skip disabled/limited/cooldown.
while (checkedKeys < this.apiKeys.length) { // This ensures all parallel items use the same key until it's actually exhausted.
const apiKey = this.apiKeys[this.currentKeyIndex]; for (let keyIdx = 0; keyIdx < this.apiKeys.length; keyIdx += 1) {
checkedKeys += 1; const apiKey = this.apiKeys[keyIdx];
const keyLabel = this.apiKeys.length > 1 ? ` (${apiKey.label})` : ""; const keyLabel = this.apiKeys.length > 1 ? ` (${apiKey.label})` : "";
if (isDebridLinkApiKeyDisabled(settings, apiKey.id)) { if (isDebridLinkApiKeyDisabled(settings, apiKey.id)) {
logger.info(`Debrid-Link${keyLabel}: uebersprungen (manuell deaktiviert), pruefe naechsten Key`); logger.info(`Debrid-Link${keyLabel}: uebersprungen (manuell deaktiviert), pruefe naechsten Key`);
this.currentKeyIndex = (this.currentKeyIndex + 1) % this.apiKeys.length;
continue; continue;
} }
if (isDebridLinkApiKeyDailyLimitReached(settings, apiKey.id)) { if (isDebridLinkApiKeyDailyLimitReached(settings, apiKey.id)) {
logger.info(`Debrid-Link${keyLabel}: uebersprungen (lokales Tageslimit erreicht), pruefe naechsten Key`); logger.info(`Debrid-Link${keyLabel}: uebersprungen (lokales Tageslimit erreicht), pruefe naechsten Key`);
this.currentKeyIndex = (this.currentKeyIndex + 1) % this.apiKeys.length;
continue; continue;
} }
const keyCooldownExpiry = debridLinkKeyCooldowns.get(apiKey.id); const keyCooldownExpiry = debridLinkKeyCooldowns.get(apiKey.id);
if (keyCooldownExpiry && Date.now() < keyCooldownExpiry) { if (keyCooldownExpiry && Date.now() < keyCooldownExpiry) {
logger.info(`Debrid-Link${keyLabel}: uebersprungen (Cooldown bis ${new Date(keyCooldownExpiry).toLocaleTimeString()}), pruefe naechsten Key`); logger.info(`Debrid-Link${keyLabel}: uebersprungen (Cooldown bis ${new Date(keyCooldownExpiry).toLocaleTimeString()}), pruefe naechsten Key`);
this.currentKeyIndex = (this.currentKeyIndex + 1) % this.apiKeys.length;
continue; continue;
} }
@ -1579,9 +1575,8 @@ class DebridLinkClient {
} }
} }
this.currentKeyIndex = (this.currentKeyIndex + 1) % this.apiKeys.length; if (keyIdx + 1 < this.apiKeys.length) {
if (checkedKeys < this.apiKeys.length) { const nextKey = this.apiKeys[keyIdx + 1];
const nextKey = this.apiKeys[this.currentKeyIndex];
const nextKeyLabel = this.apiKeys.length > 1 ? ` (${nextKey.label})` : ""; const nextKeyLabel = this.apiKeys.length > 1 ? ` (${nextKey.label})` : "";
logger.info(`Debrid-Link${keyLabel}: kein Erfolg, wechsle zu naechstem Key${nextKeyLabel}`); logger.info(`Debrid-Link${keyLabel}: kein Erfolg, wechsle zu naechstem Key${nextKeyLabel}`);
} }