Fix final post-process requeue stall

This commit is contained in:
Sucukdeluxe 2026-03-09 05:33:09 +01:00
parent 49066f51bc
commit 3de4ba3e90
3 changed files with 110 additions and 2 deletions

View File

@ -4989,6 +4989,14 @@ export class DownloadManager extends EventEmitter {
});
}
private shouldCollapseQuickPostProcessRequeue(packageId: string): boolean {
const pkg = this.session.packages[packageId];
if (!pkg) {
return true;
}
return !this.areAllPackageItemRefsFinished(pkg);
}
private async findFullExtractArchiveSet(pkg: PackageEntry, completedItems: DownloadItem[]): Promise<Set<string>> {
const relevant = new Set<string>();
if (!pkg.outputDir || completedItems.length === 0) {
@ -5499,7 +5507,9 @@ export class DownloadManager extends EventEmitter {
// rounds when many small archive parts complete in rapid
// succession (e.g. 15-20 × 101 MB parts per episode).
if (roundMs < 2000 && this.hybridExtractRequeue.has(packageId)) {
this.hybridExtractRequeue.delete(packageId);
if (this.shouldCollapseQuickPostProcessRequeue(packageId)) {
this.hybridExtractRequeue.delete(packageId);
}
}
} while (this.hybridExtractRequeue.has(packageId));
} finally {

View File

@ -5538,7 +5538,7 @@ export function App(): ReactElement {
void window.rd.openItemLog(id).catch(() => {});
}
setContextMenu(null);
}}>Item-Log Ãffnen{multi ? ` (${selectedItemIds.length})` : ""}</button>
}}>Item-Log öffnen{multi ? ` (${selectedItemIds.length})` : ""}</button>
)}
<div className="ctx-menu-sep" />
{hasPackages && !contextMenu.itemId && (

View File

@ -129,6 +129,104 @@ describe("download manager", () => {
expect(historyEntries[0]?.downloadedBytes).toBe(90 * 1024 * 1024);
});
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);
const session = emptySession();
const packageId = "postprocess-final-pkg";
const firstItemId = "postprocess-final-item-1";
const secondItemId = "postprocess-final-item-2";
const createdAt = Date.now() - 20_000;
const packageOutputDir = path.join(root, "downloads", "PostProcess Final Round");
const packageExtractDir = path.join(root, "extract", "PostProcess Final Round");
fs.mkdirSync(packageOutputDir, { recursive: true });
fs.mkdirSync(packageExtractDir, { recursive: true });
fs.writeFileSync(path.join(packageOutputDir, "final-1.rar"), Buffer.alloc(100, 1));
session.packageOrder = [packageId];
session.packages[packageId] = {
id: packageId,
name: "PostProcess Final Round",
outputDir: packageOutputDir,
extractDir: packageExtractDir,
status: "downloading",
itemIds: [firstItemId, secondItemId],
cancelled: false,
enabled: true,
createdAt,
updatedAt: createdAt
};
session.items[firstItemId] = {
id: firstItemId,
packageId,
url: "https://example.com/final-1.rar",
provider: "realdebrid",
status: "completed",
retries: 0,
speedBps: 0,
downloadedBytes: 100,
totalBytes: 100,
progressPercent: 100,
fileName: "final-1.rar",
targetPath: path.join(packageOutputDir, "final-1.rar"),
resumable: true,
attempts: 1,
lastError: "",
fullStatus: "Entpackt - Done (<1s)",
createdAt,
updatedAt: createdAt
};
session.items[secondItemId] = {
id: secondItemId,
packageId,
url: "https://example.com/final-2.rar",
provider: "realdebrid",
status: "downloading",
retries: 0,
speedBps: 0,
downloadedBytes: 90,
totalBytes: 100,
progressPercent: 90,
fileName: "final-2.rar",
targetPath: path.join(packageOutputDir, "final-2.rar"),
resumable: true,
attempts: 1,
lastError: "",
fullStatus: "Download läuft",
createdAt,
updatedAt: createdAt
};
const manager = new DownloadManager(
{
...defaultSettings(),
token: "rd-token",
outputDir: path.join(root, "downloads"),
extractDir: path.join(root, "extract"),
autoExtract: true,
hybridExtract: true
},
session,
createStoragePaths(path.join(root, "state"))
);
expect((manager as any).shouldCollapseQuickPostProcessRequeue(packageId)).toBe(true);
const item = (manager as any).session.items[secondItemId];
item.status = "completed";
item.downloadedBytes = item.totalBytes;
item.progressPercent = 100;
item.fullStatus = "Entpacken - Ausstehend";
item.updatedAt = Date.now();
expect((manager as any).session.items[firstItemId].status).toBe("completed");
expect((manager as any).session.items[secondItemId].status).toBe("completed");
expect((manager as any).session.packages[packageId].itemIds).toEqual([firstItemId, secondItemId]);
expect((manager as any).shouldCollapseQuickPostProcessRequeue(packageId)).toBe(false);
});
function createCompletedArchiveSession(root: string, packageName: string, extractedFileName: string): {
session: ReturnType<typeof emptySession>;
packageId: string;