fix(extraction): isolate explicit jobs and run cancellation
Use validated explicit archive paths without recursively discovering a shared package root. Route selective post-processing stops through the coordinator run owner so another generation of the same package remains active, while preserving unfiltered package cancellation behavior.
This commit is contained in:
@@ -7178,9 +7178,6 @@ export class DownloadManager extends EventEmitter {
|
||||
this.speedBytesPerPackage.clear();
|
||||
this.speedEventsHead = 0;
|
||||
this.abortPostProcessing("stop", stoppedRunContext?.id);
|
||||
if (stoppedRunContext) {
|
||||
void this.extractionCoordinator.cancelRun(stoppedRunContext.id, "stop");
|
||||
}
|
||||
for (const active of this.activeTasks.values()) {
|
||||
active.abortReason = abortReason;
|
||||
active.abortController.abort(abortReason);
|
||||
@@ -8761,12 +8758,17 @@ export class DownloadManager extends EventEmitter {
|
||||
}
|
||||
|
||||
private abortPostProcessing(reason: string, runContextId?: string): void {
|
||||
if (runContextId !== undefined) {
|
||||
void this.extractionCoordinator.cancelRun(runContextId, reason);
|
||||
}
|
||||
for (const [packageId, controller] of this.packagePostProcessAbortControllers.entries()) {
|
||||
const owner = this.packagePostProcessRunOwnerByController.get(controller);
|
||||
if (runContextId !== undefined && owner !== runContextId) {
|
||||
continue;
|
||||
}
|
||||
void this.extractionCoordinator.cancelPackage(packageId, reason);
|
||||
if (runContextId === undefined) {
|
||||
void this.extractionCoordinator.cancelPackage(packageId, reason);
|
||||
}
|
||||
if (!controller.signal.aborted) {
|
||||
controller.abort(reason);
|
||||
}
|
||||
@@ -8801,7 +8803,9 @@ export class DownloadManager extends EventEmitter {
|
||||
if (runContextId !== undefined && owner !== runContextId) {
|
||||
continue;
|
||||
}
|
||||
void this.extractionCoordinator.cancelPackage(packageId, reason);
|
||||
if (runContextId === undefined) {
|
||||
void this.extractionCoordinator.cancelPackage(packageId, reason);
|
||||
}
|
||||
if (!controller.signal.aborted) {
|
||||
controller.abort(reason);
|
||||
}
|
||||
@@ -8812,7 +8816,9 @@ export class DownloadManager extends EventEmitter {
|
||||
if (runContextId !== undefined && owner !== runContextId) {
|
||||
continue;
|
||||
}
|
||||
void this.extractionCoordinator.cancelPackage(packageId, reason);
|
||||
if (runContextId === undefined) {
|
||||
void this.extractionCoordinator.cancelPackage(packageId, reason);
|
||||
}
|
||||
if (!controller.signal.aborted) {
|
||||
controller.abort(reason);
|
||||
}
|
||||
|
||||
+28
-11
@@ -3656,16 +3656,33 @@ export async function extractPackageArchives(options: ExtractOptions): Promise<E
|
||||
const validateOutputTarget = (entryPath: string, outputPath: string): void => {
|
||||
outputScope.validateTarget(entryPath, outputPath);
|
||||
};
|
||||
options.onProgress?.({ current: 0, total: 0, percent: 0, archiveName: "Archive scannen...", phase: "preparing" });
|
||||
const allCandidates = await findArchiveCandidates(options.packageDir);
|
||||
const candidates = options.onlyArchives
|
||||
? allCandidates.filter((archivePath) => {
|
||||
const key = process.platform === "win32" ? path.resolve(archivePath).toLowerCase() : path.resolve(archivePath);
|
||||
return options.onlyArchives!.has(key);
|
||||
})
|
||||
: allCandidates;
|
||||
logger.info(`Entpacken gestartet: packageDir=${options.packageDir}, targetDir=${options.targetDir}, archives=${candidates.length}${options.onlyArchives ? ` (hybrid, gesamt=${allCandidates.length})` : ""}, cleanupMode=${options.cleanupMode}, conflictMode=${options.conflictMode}`);
|
||||
options.onLog?.("INFO", `Entpacken gestartet: packageDir=${options.packageDir}, targetDir=${options.targetDir}, archives=${candidates.length}${options.onlyArchives ? ` (hybrid, gesamt=${allCandidates.length})` : ""}, cleanupMode=${options.cleanupMode}, conflictMode=${options.conflictMode}`);
|
||||
options.onProgress?.({ current: 0, total: 0, percent: 0, archiveName: "Archive scannen...", phase: "preparing" });
|
||||
const candidates: string[] = [];
|
||||
if (options.onlyArchives) {
|
||||
const packageRoot = path.resolve(options.packageDir);
|
||||
const inputScope = new PackageOutputScope([packageRoot]);
|
||||
const seen = new Set<string>();
|
||||
for (const archivePath of options.onlyArchives) {
|
||||
const candidate = path.resolve(String(archivePath));
|
||||
const entryPath = path.relative(packageRoot, candidate).replace(/\\/g, "/");
|
||||
inputScope.validateTarget(entryPath, candidate);
|
||||
let stat: fs.Stats;
|
||||
try {
|
||||
stat = await fs.promises.lstat(candidate);
|
||||
} catch {
|
||||
continue;
|
||||
}
|
||||
const key = pathSetKey(candidate);
|
||||
if (stat.isFile() && !stat.isSymbolicLink() && !seen.has(key)) {
|
||||
seen.add(key);
|
||||
candidates.push(candidate);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
candidates.push(...await findArchiveCandidates(options.packageDir));
|
||||
}
|
||||
logger.info(`Entpacken gestartet: packageDir=${options.packageDir}, targetDir=${options.targetDir}, archives=${candidates.length}${options.onlyArchives ? " (explizite Liste)" : ""}, cleanupMode=${options.cleanupMode}, conflictMode=${options.conflictMode}`);
|
||||
options.onLog?.("INFO", `Entpacken gestartet: packageDir=${options.packageDir}, targetDir=${options.targetDir}, archives=${candidates.length}${options.onlyArchives ? " (explizite Liste)" : ""}, cleanupMode=${options.cleanupMode}, conflictMode=${options.conflictMode}`);
|
||||
|
||||
if (candidates.length > 0) {
|
||||
options.onProgress?.({ current: 0, total: candidates.length, percent: 0, archiveName: "Speicherplatz prüfen...", phase: "preparing" });
|
||||
@@ -4303,7 +4320,7 @@ export async function extractPackageArchives(options: ExtractOptions): Promise<E
|
||||
}
|
||||
}
|
||||
|
||||
if (failed === 0 && resumeCompleted.size >= allCandidates.length && !options.skipPostCleanup) {
|
||||
if (!options.onlyArchives && failed === 0 && resumeCompleted.size >= candidates.length && !options.skipPostCleanup) {
|
||||
await clearExtractResumeState(options.packageDir, options.packageId);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user