Fix: Mega-Debrid-Rotation verteilt jetzt ueber ALLE Accounts (Round-Robin statt First-Wins)
Symptom (User): 4 Accounts hinterlegt, aber die Rotation nutzte nur die Accounts 1-3 — der 4. wurde nie angefasst, ausser man deaktivierte die anderen manuell. Ursache (im Live-Log des Servers belegt, rd_downloader.log): Die Account-Schleife in unrestrictWithAccounts startete bei JEDER Link-Aufloesung bei Account 1 und nahm den ersten brauchbaren (First-Usable-Wins-Failover). Ein spaeterer Account kam nur dran, wenn ALLE davor am Tageslimit/Cooldown/deaktiviert waren. Live-Verteilung: Account 1 = 749 OK + 1314x "Tageslimit — bis Neustart gesperrt", Account 2 = 1733 OK + 448x Tageslimit-Sperre, Account 3 = 1603 OK ohne ein einziges Limit — die Kette endete deshalb IMMER spaetestens bei Account 3, und Account 4 tauchte im gesamten Log mit keinem einzigen Event auf (nicht getestet, nicht geskippt). Accounts 1-2 liefen also staendig ins Tageslimit, waehrend die Kapazitaet von Account 4 jeden Tag verfiel. Fix: Round-Robin-Cursor in unrestrictWithAccounts. Jede Aufloesung startet beim Account NACH dem zuletzt getesteten (Modulo ueber die Liste), alle bestehenden Checks (deaktiviert, lokales Tageslimit, Cooldown, Park-bis-Neustart) bleiben unveraendert und werden in der neuen Reihenfolge durchlaufen. Damit verteilen sich Links gleichmaessig ueber alle Accounts, kein Account wird mehr stumpf bis ans Limit gehaemmert, und Account 4 nimmt automatisch teil. Der Cursor ist Modul-State (bei App-Neustart wieder Account 1), die "naechster Account"-Vorschau im Fehlerpfad folgt der Modulo-Reihenfolge, und resetMegaDebridRuntimeStateForTests setzt ihn fuer deterministische Tests zurueck. Die Debrid-Link-Key-Rotation (separate Schleife) bleibt unveraendert First-Wins — dort ist kein Account konfiguriert; bei Bedarf gleiches Muster nachziehen. Nebenfix: Das Support-Bundle exportiert jetzt auch logs/account-rotation.log (+ .old) — genau dieses Log fehlte im Bundle und haette die Diagnose sofort geliefert (die Datei kollidiert namentlich mit dem gleichnamigen Log des Multi-Hoster-Uploaders, daher war zunaechst das falsche Log in der Analyse). Tests: 2 neue Regressionstests (5 Links auf 4 Accounts -> 1,2,3,4,1; Cooldown-Account wird in der Reihe uebersprungen), Suite 806 gruen, tsc=6 Baseline, self-check + build ok.
This commit is contained in:
@@ -1379,6 +1379,90 @@ describe("debrid service", () => {
|
||||
}
|
||||
});
|
||||
|
||||
it("verteilt Links per Round-Robin ueber ALLE Mega-Debrid-Accounts statt immer beim ersten zu starten", async () => {
|
||||
const settings = {
|
||||
...defaultSettings(),
|
||||
token: "",
|
||||
bestToken: "",
|
||||
allDebridToken: "",
|
||||
megaLogin: "user1",
|
||||
megaPassword: "pass1",
|
||||
megaCredentials: "user1:pass1\nuser2:pass2\nuser3:pass3\nuser4:pass4",
|
||||
megaDebridPreferApi: false,
|
||||
providerOrder: [] as const,
|
||||
providerPrimary: "megadebrid" as const,
|
||||
providerSecondary: "none" as const,
|
||||
providerTertiary: "none" as const,
|
||||
autoProviderFallback: false
|
||||
};
|
||||
|
||||
globalThis.fetch = (async () => new Response("error", { status: 500 })) as typeof fetch;
|
||||
|
||||
const megaWeb = vi.fn(async () => ({
|
||||
fileName: "ok.rar",
|
||||
directUrl: "https://mega-web.example/ok.rar",
|
||||
fileSize: null,
|
||||
retriesUsed: 0
|
||||
}));
|
||||
|
||||
const service = new DebridService(settings, { megaWebUnrestrict: megaWeb });
|
||||
const usedIds: (string | undefined)[] = [];
|
||||
for (let i = 0; i < 5; i += 1) {
|
||||
const result = await service.unrestrictLink(`https://rapidgator.net/file/rr-${i}`);
|
||||
usedIds.push((result as { sourceAccountId?: string }).sourceAccountId);
|
||||
}
|
||||
|
||||
expect(usedIds).toEqual([
|
||||
getMegaDebridAccountId("user1"),
|
||||
getMegaDebridAccountId("user2"),
|
||||
getMegaDebridAccountId("user3"),
|
||||
getMegaDebridAccountId("user4"),
|
||||
getMegaDebridAccountId("user1")
|
||||
]);
|
||||
}, 30000);
|
||||
|
||||
it("Round-Robin respektiert Cooldowns: gesperrter Account wird in der Reihe uebersprungen", async () => {
|
||||
const settings = {
|
||||
...defaultSettings(),
|
||||
token: "",
|
||||
bestToken: "",
|
||||
allDebridToken: "",
|
||||
megaLogin: "user1",
|
||||
megaPassword: "pass1",
|
||||
megaCredentials: "user1:pass1\nuser2:pass2\nuser3:pass3",
|
||||
megaDebridPreferApi: false,
|
||||
providerOrder: [] as const,
|
||||
providerPrimary: "megadebrid" as const,
|
||||
providerSecondary: "none" as const,
|
||||
providerTertiary: "none" as const,
|
||||
autoProviderFallback: false
|
||||
};
|
||||
|
||||
globalThis.fetch = (async () => new Response("error", { status: 500 })) as typeof fetch;
|
||||
|
||||
const megaWeb = vi.fn(async () => ({
|
||||
fileName: "ok.rar",
|
||||
directUrl: "https://mega-web.example/ok.rar",
|
||||
fileSize: null,
|
||||
retriesUsed: 0
|
||||
}));
|
||||
|
||||
primeMegaDebridUntilRestartForTests(`${getMegaDebridAccountId("user2")}:web`);
|
||||
|
||||
const service = new DebridService(settings, { megaWebUnrestrict: megaWeb });
|
||||
const usedIds: (string | undefined)[] = [];
|
||||
for (let i = 0; i < 3; i += 1) {
|
||||
const result = await service.unrestrictLink(`https://rapidgator.net/file/rr-skip-${i}`);
|
||||
usedIds.push((result as { sourceAccountId?: string }).sourceAccountId);
|
||||
}
|
||||
|
||||
expect(usedIds).toEqual([
|
||||
getMegaDebridAccountId("user1"),
|
||||
getMegaDebridAccountId("user3"),
|
||||
getMegaDebridAccountId("user1")
|
||||
]);
|
||||
}, 30000);
|
||||
|
||||
it("rotates to the next Mega-Debrid account when one hits its daily limit (error-based)", async () => {
|
||||
const settings = {
|
||||
...defaultSettings(),
|
||||
|
||||
Reference in New Issue
Block a user