Fix hybrid extraction skipping archives when item status stuck
Build and Release / build (push) Has been cancelled
Build and Release / build (push) Has been cancelled
Add disk-fallback to findReadyArchiveSets: when all archive parts physically exist on disk with non-zero size and none are actively downloading/validating, consider the archive ready for extraction. This fixes episodes being skipped when a download item's status was not updated to "completed" despite the file being fully written. Also improve debug server: raise log limit to 10000 lines, add grep filter, add /session endpoint for raw session data. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
9f589439a1
commit
d8a53dcea6
@@ -4472,20 +4472,59 @@ export class DownloadManager extends EventEmitter {
|
||||
return ready;
|
||||
}
|
||||
|
||||
// Build lookup: pathKey → item status for pending items
|
||||
const pendingItemStatus = new Map<string, string>();
|
||||
for (const itemId of pkg.itemIds) {
|
||||
const item = this.session.items[itemId];
|
||||
if (item && item.targetPath && item.status !== "completed") {
|
||||
pendingItemStatus.set(pathKey(item.targetPath), item.status);
|
||||
}
|
||||
}
|
||||
|
||||
for (const candidate of candidates) {
|
||||
const partsOnDisk = collectArchiveCleanupTargets(candidate, dirFiles);
|
||||
const allPartsCompleted = partsOnDisk.every((part) => completedPaths.has(pathKey(part)));
|
||||
if (!allPartsCompleted) {
|
||||
if (allPartsCompleted) {
|
||||
const hasUnstartedParts = [...pendingPaths].some((pendingPath) => {
|
||||
const pendingName = path.basename(pendingPath).toLowerCase();
|
||||
const candidateStem = path.basename(candidate).toLowerCase();
|
||||
return this.looksLikeArchivePart(pendingName, candidateStem);
|
||||
});
|
||||
if (hasUnstartedParts) {
|
||||
continue;
|
||||
}
|
||||
ready.add(pathKey(candidate));
|
||||
continue;
|
||||
}
|
||||
const hasUnstartedParts = [...pendingPaths].some((pendingPath) => {
|
||||
const pendingName = path.basename(pendingPath).toLowerCase();
|
||||
const candidateStem = path.basename(candidate).toLowerCase();
|
||||
return this.looksLikeArchivePart(pendingName, candidateStem);
|
||||
|
||||
// Disk-fallback: if all parts exist on disk but some items lack "completed" status,
|
||||
// allow extraction if none of those parts are actively downloading/validating.
|
||||
// This handles items that finished downloading but whose status was not updated.
|
||||
const missingParts = partsOnDisk.filter((part) => !completedPaths.has(pathKey(part)));
|
||||
let allMissingExistOnDisk = true;
|
||||
for (const part of missingParts) {
|
||||
try {
|
||||
const stat = fs.statSync(part);
|
||||
if (stat.size <= 0) {
|
||||
allMissingExistOnDisk = false;
|
||||
break;
|
||||
}
|
||||
} catch {
|
||||
allMissingExistOnDisk = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!allMissingExistOnDisk) {
|
||||
continue;
|
||||
}
|
||||
const anyActivelyProcessing = missingParts.some((part) => {
|
||||
const status = pendingItemStatus.get(pathKey(part));
|
||||
return status === "downloading" || status === "validating" || status === "integrity_check";
|
||||
});
|
||||
if (hasUnstartedParts) {
|
||||
if (anyActivelyProcessing) {
|
||||
continue;
|
||||
}
|
||||
logger.info(`Hybrid-Extract Disk-Fallback: ${path.basename(candidate)} (${missingParts.length} Part(s) auf Disk ohne completed-Status)`);
|
||||
ready.add(pathKey(candidate));
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user