Compare commits
No commits in common. "3acaf178edc5f4ebfd567e0918c15749a8884a75" and "ce573fe7b6fd30daa5f5bb2a5c76560df48a9b74" have entirely different histories.
3acaf178ed
...
ce573fe7b6
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "real-debrid-downloader",
|
||||
"version": "1.7.229",
|
||||
"version": "1.7.228",
|
||||
"description": "Desktop downloader",
|
||||
"main": "build/main/main/main.js",
|
||||
"author": "Sucukdeluxe",
|
||||
|
||||
@ -339,25 +339,6 @@ export function resetMegaDebridRuntimeStateForTests(): void {
|
||||
megaDebridInFlight.clear();
|
||||
}
|
||||
|
||||
export function getMegaDebridInFlightCountForMode(mode: "api" | "web"): number {
|
||||
const suffix = `:${mode}`;
|
||||
let total = 0;
|
||||
for (const [key, count] of megaDebridInFlight) {
|
||||
if (key.endsWith(suffix)) {
|
||||
total += count;
|
||||
}
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
export function primeMegaDebridInFlightForTests(key: string, count: number): void {
|
||||
if (count <= 0) {
|
||||
megaDebridInFlight.delete(key);
|
||||
return;
|
||||
}
|
||||
megaDebridInFlight.set(key, count);
|
||||
}
|
||||
|
||||
export function pruneExpiredMegaDebridRuntimeState(now = Date.now()): number {
|
||||
let removed = 0;
|
||||
const grace = 60 * 60 * 1000;
|
||||
|
||||
@ -52,7 +52,7 @@ function releaseTlsSkip(): void {
|
||||
}
|
||||
import { cleanupCancelledPackageArtifactsAsync, removeDownloadLinkArtifacts, removeSampleArtifacts } from "./cleanup";
|
||||
import { planDownloadCompletion, reconcileFinalizedSize, validateDownloadedFileCompletion } from "./download-completion";
|
||||
import { AllDebridWebUnrestrictor, BestDebridWebUnrestrictor, DebridService, MegaWebUnrestrictor, RealDebridWebUnrestrictor, checkRapidgatorOnline, fetchAllDebridHostInfo, getAvailableDebridLinkApiKeys, getAvailableMegaDebridAccounts, getMegaDebridAccountCooldownState, getMegaDebridInFlightCountForMode, pruneExpiredDebridLinkRuntimeState, pruneExpiredMegaDebridRuntimeState } from "./debrid";
|
||||
import { AllDebridWebUnrestrictor, BestDebridWebUnrestrictor, DebridService, MegaWebUnrestrictor, RealDebridWebUnrestrictor, checkRapidgatorOnline, fetchAllDebridHostInfo, getAvailableDebridLinkApiKeys, getAvailableMegaDebridAccounts, getMegaDebridAccountCooldownState, pruneExpiredDebridLinkRuntimeState, pruneExpiredMegaDebridRuntimeState } from "./debrid";
|
||||
import { cleanupArchives, clearExtractResumeState, collectArchiveCleanupTargets, detectArchiveSignature, extractPackageArchives, findArchiveCandidates, hasAnyFilesRecursive, removeEmptyDirectoryTree, resetExtractorCachesForPasswordChange, type ExtractArchiveFailureInfo } from "./extractor";
|
||||
import { validateFileAgainstManifest } from "./integrity";
|
||||
import { classifyDiskError } from "./fs-error";
|
||||
@ -8212,13 +8212,7 @@ export class DownloadManager extends EventEmitter {
|
||||
const provider = resolveMegaDebridProvider(this.settings, this.getExpectedProviderForItem(item));
|
||||
const serializedValidatingLimit = this.getSerializedValidatingLimit(provider);
|
||||
if (provider && Number.isFinite(serializedValidatingLimit) && serializedValidatingLimit < Number.MAX_SAFE_INTEGER) {
|
||||
const validating = this.getProviderValidatingTaskCount(provider, item.id);
|
||||
if (provider === "megadebrid-api") {
|
||||
const webInFlight = getMegaDebridInFlightCountForMode("web");
|
||||
const overlapAllowance = Math.min(serializedValidatingLimit, webInFlight);
|
||||
return validating >= serializedValidatingLimit + overlapAllowance;
|
||||
}
|
||||
return validating >= serializedValidatingLimit;
|
||||
return this.getProviderValidatingTaskCount(provider, item.id) >= serializedValidatingLimit;
|
||||
}
|
||||
if (provider !== "alldebrid") {
|
||||
return false;
|
||||
|
||||
@ -14,7 +14,7 @@ import { getProviderUsageDayKey } from "../src/shared/provider-daily-limits";
|
||||
import { getItemLogPath, initItemLogs, shutdownItemLogs } from "../src/main/item-log";
|
||||
import { initPackageLogs, shutdownPackageLogs } from "../src/main/package-log";
|
||||
import { createStoragePaths, emptySession } from "../src/main/storage";
|
||||
import { primeDebridLinkRuntimeCooldownForTests, resetDebridLinkRuntimeStateForTests, primeMegaDebridRuntimeCooldownForTests, resetMegaDebridRuntimeStateForTests, primeMegaDebridInFlightForTests } from "../src/main/debrid";
|
||||
import { primeDebridLinkRuntimeCooldownForTests, resetDebridLinkRuntimeStateForTests, primeMegaDebridRuntimeCooldownForTests, resetMegaDebridRuntimeStateForTests } from "../src/main/debrid";
|
||||
import { getMegaDebridAccountId } from "../src/shared/mega-debrid-accounts";
|
||||
import { getRenameLogPath, initRenameLog, shutdownRenameLog } from "../src/main/rename-log";
|
||||
import { UnrestrictedLink } from "../src/main/realdebrid";
|
||||
@ -12362,82 +12362,3 @@ describe("start conflict guard + selective resume", () => {
|
||||
manager.stop();
|
||||
});
|
||||
});
|
||||
|
||||
describe("mega-debrid api/web resolution overlap gate", () => {
|
||||
function megaApiSettings(root: string): any {
|
||||
return {
|
||||
...defaultSettings(),
|
||||
megaLogin: "u", megaPassword: "p", megaCredentials: "u:p",
|
||||
megaDebridApiEnabled: true, megaDebridWebEnabled: true, megaDebridPreferApi: true,
|
||||
outputDir: path.join(root, "downloads"), extractDir: path.join(root, "extract")
|
||||
};
|
||||
}
|
||||
|
||||
function megaItem(id: string, status: string): any {
|
||||
return {
|
||||
id, packageId: "pkg", url: `https://rapidgator.net/file/${id}`, provider: "megadebrid-api",
|
||||
status, retries: 0, speedBps: 0, downloadedBytes: 0, totalBytes: null, progressPercent: 0,
|
||||
fileName: `${id}.rar`, targetPath: "", resumable: true, attempts: 0, lastError: "", fullStatus: "",
|
||||
createdAt: Date.now(), updatedAt: Date.now()
|
||||
};
|
||||
}
|
||||
|
||||
function addValidating(manager: DownloadManager, session: any, ids: string[]): void {
|
||||
for (const id of ids) {
|
||||
session.items[id] = megaItem(id, "validating");
|
||||
(manager as any).activeTasks.set(id, {
|
||||
itemId: id, packageId: "pkg", abortController: new AbortController(), abortReason: "none",
|
||||
resumable: true, nonResumableCounted: false, blockedOnDiskWrite: false, blockedOnDiskSince: 0
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function buildManager(root: string, session: any): DownloadManager {
|
||||
return new DownloadManager(megaApiSettings(root), session, createStoragePaths(path.join(root, "state")));
|
||||
}
|
||||
|
||||
it("lets the first mega resolve start when nothing is in flight", () => {
|
||||
const root = fs.mkdtempSync(path.join(os.tmpdir(), "rd-overlap-0-"));
|
||||
tempDirs.push(root);
|
||||
const session = emptySession();
|
||||
const candidate = megaItem("cand", "queued");
|
||||
session.items["cand"] = candidate;
|
||||
const manager = buildManager(root, session);
|
||||
expect((manager as any).shouldDelayStartForItem(candidate)).toBe(false);
|
||||
});
|
||||
|
||||
it("serializes a second API resolve while the first is still in its API phase (no concurrent API)", () => {
|
||||
const root = fs.mkdtempSync(path.join(os.tmpdir(), "rd-overlap-1-"));
|
||||
tempDirs.push(root);
|
||||
const session = emptySession();
|
||||
const candidate = megaItem("cand", "queued");
|
||||
session.items["cand"] = candidate;
|
||||
const manager = buildManager(root, session);
|
||||
addValidating(manager, session, ["a"]);
|
||||
expect((manager as any).shouldDelayStartForItem(candidate)).toBe(true);
|
||||
});
|
||||
|
||||
it("allows one API resolve to overlap once the first has moved to its web phase", () => {
|
||||
const root = fs.mkdtempSync(path.join(os.tmpdir(), "rd-overlap-2-"));
|
||||
tempDirs.push(root);
|
||||
const session = emptySession();
|
||||
const candidate = megaItem("cand", "queued");
|
||||
session.items["cand"] = candidate;
|
||||
const manager = buildManager(root, session);
|
||||
addValidating(manager, session, ["a"]);
|
||||
primeMegaDebridInFlightForTests("acc:web", 1);
|
||||
expect((manager as any).shouldDelayStartForItem(candidate)).toBe(false);
|
||||
});
|
||||
|
||||
it("caps the overlap at one API plus one web (no third concurrent resolve)", () => {
|
||||
const root = fs.mkdtempSync(path.join(os.tmpdir(), "rd-overlap-3-"));
|
||||
tempDirs.push(root);
|
||||
const session = emptySession();
|
||||
const candidate = megaItem("cand", "queued");
|
||||
session.items["cand"] = candidate;
|
||||
const manager = buildManager(root, session);
|
||||
addValidating(manager, session, ["a", "b"]);
|
||||
primeMegaDebridInFlightForTests("acc:web", 1);
|
||||
expect((manager as any).shouldDelayStartForItem(candidate)).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
Loading…
Reference in New Issue
Block a user