Test: No-Stranding-Gate fuer Provider-Fallback-Routing + Doku-Praezisierung
findFallbackProviderNotInCooldown-Charakterisierungstest sichert den Invariant
ab, auf dem der Routing-Fix (986fbab) seine Sicherheit aufbaut: bei kein
Cooldown den ersten Provider, bei einem Cooldown den naechsten gesunden, und
NULL erst wenn ALLE Provider im Cooldown sind. Dieses null ist der Punkt, an
dem der Aufrufer queueRetry statt Reorder macht — wuerde der Helper hier je
einen abgekuehlten Provider als letzten Notnagel zurueckgeben, liefe der
Reorder am Sicherheitsnetz vorbei. Der Test friert das ein.
Zusaetzlich: entscheidungen-offen.md praezisiert, dass Option A des Failover-
Timeouts ein Drehregler ueber den Pro-Provider-Wert ist (30s/90s, 60s/180s),
kein fixer Wert.
This commit is contained in:
parent
986fbab04f
commit
03c908bd30
@ -26,10 +26,12 @@ trifft in der Produktion derzeit selten. Deshalb dokumentiert statt dringend gef
|
||||
|
||||
**Deine Entscheidung — zwei Richtungen (gleiche Spannung, andere Seite):**
|
||||
|
||||
- **A) Pro-Provider-Timeout:** Jeder Provider bekommt sein eigenes frisches 60s-Budget.
|
||||
- **A) Pro-Provider-Timeout:** Jeder Provider bekommt sein eigenes frisches Budget.
|
||||
Failover bekommt IMMER einen echten Versuch.
|
||||
*Kosten:* Worst-Case-Wartezeit pro Item steigt (3 Provider × 60s = bis zu 180s, bevor ein
|
||||
Item aufgibt). Du akzeptierst langsameres Worst-Case-pro-Item für vollständigeres Failover.
|
||||
*Kosten:* Worst-Case-Wartezeit pro Item steigt. Das Budget ist dabei ein DREHregler, kein
|
||||
fixer Wert: 60s/Provider = bis 180s Worst-Case (3 Provider), 30s/Provider = bis 90s usw.
|
||||
Du akzeptierst langsameres Worst-Case-pro-Item für vollständigeres Failover — und stellst
|
||||
über den Pro-Provider-Wert ein, wie viel langsamer.
|
||||
|
||||
- **B) Globales Budget behalten, aber Slice für Failover reservieren:** Provider 1 wird auf
|
||||
z.B. 35s gedeckelt, damit garantiert Zeit für Provider 2 bleibt.
|
||||
|
||||
@ -229,6 +229,34 @@ describe("download manager", () => {
|
||||
expect(historyEntries[0]?.downloadedBytes).toBe(90 * 1024 * 1024);
|
||||
});
|
||||
|
||||
it("findFallbackProviderNotInCooldown routes around cooled providers and returns null only when all are cooled", () => {
|
||||
const root = fs.mkdtempSync(path.join(os.tmpdir(), "rd-fallback-route-"));
|
||||
tempDirs.push(root);
|
||||
const manager = new DownloadManager(
|
||||
{
|
||||
...defaultSettings(),
|
||||
token: "rd-token",
|
||||
debridLinkApiKeys: "dl-token",
|
||||
providerOrder: ["realdebrid", "debridlink"],
|
||||
providerPrimary: "realdebrid",
|
||||
providerSecondary: "debridlink",
|
||||
providerTertiary: "none",
|
||||
autoProviderFallback: true
|
||||
},
|
||||
emptySession(),
|
||||
createStoragePaths(path.join(root, "state"))
|
||||
);
|
||||
const item = { id: "fb-item", url: "https://hoster.example/file.bin", provider: "realdebrid" } as any;
|
||||
|
||||
expect((manager as any).findFallbackProviderNotInCooldown(item)).toBe("realdebrid");
|
||||
|
||||
(manager as any).applyProviderBusyBackoff("realdebrid", 60000);
|
||||
expect((manager as any).findFallbackProviderNotInCooldown(item)).toBe("debridlink");
|
||||
|
||||
(manager as any).applyProviderBusyBackoff("debridlink", 60000);
|
||||
expect((manager as any).findFallbackProviderNotInCooldown(item)).toBeNull();
|
||||
});
|
||||
|
||||
it("keeps the quick post-process requeue once the final package items are finished", () => {
|
||||
const root = fs.mkdtempSync(path.join(os.tmpdir(), "rd-postprocess-final-"));
|
||||
tempDirs.push(root);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user