🐛 fix: addJobs tracks promises so batch-done waits for them

Previously addJobs() was fire-and-forget — added jobs ran as orphaned
promises. When the original batch completed, batch-done fired and
uploadManager was set to null while added jobs were still running.

Now: added job promises are tracked in _additionalPromises array.
startBatch drains this array after the original tasks complete,
ensuring batch-done only fires when ALL jobs (original + added) finish.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Administrator 2026-03-23 18:19:59 +01:00
parent 3c84679df1
commit ff6f7f8612

View File

@ -136,6 +136,7 @@ class UploadManager extends EventEmitter {
const batchId = `batch-${Date.now()}`; const batchId = `batch-${Date.now()}`;
const results = new Map(); // filePath -> { name, size, results: [] } const results = new Map(); // filePath -> { name, size, results: [] }
this._batchResults = results; this._batchResults = results;
this._additionalPromises = []; // Track jobs added mid-batch via addJobs()
for (const task of tasks) { for (const task of tasks) {
const fileName = path.basename(task.file); const fileName = path.basename(task.file);
@ -150,6 +151,11 @@ class UploadManager extends EventEmitter {
const promises = tasks.map((task) => this._runJob(task, results, signal)); const promises = tasks.map((task) => this._runJob(task, results, signal));
await Promise.allSettled(promises); await Promise.allSettled(promises);
// Wait for any jobs added mid-batch via addJobs()
while (this._additionalPromises.length > 0) {
const batch = this._additionalPromises.splice(0);
await Promise.allSettled(batch);
}
this._stopStatsTimer(); this._stopStatsTimer();
this.running = false; this.running = false;
@ -703,9 +709,9 @@ class UploadManager extends EventEmitter {
results.set(task.file, { name: fileName, size, results: [] }); results.set(task.file, { name: fileName, size, results: [] });
} }
} }
// Start each new job — they'll acquire semaphores and run // Start each new job and track promises so batch-done waits for them
for (const task of tasks) { for (const task of tasks) {
this._runJob(task, results, signal); this._additionalPromises.push(this._runJob(task, results, signal));
} }
} }