Skip to content

Commit 6f8acb2

Browse files
authored
Merge pull request Gnathonic#241 from Gnathonic/fix/mega-download-queue-race-condition
fix: Prevent duplicate downloads in queue due to race condition
2 parents a6db791 + 89e3b43 commit 6f8acb2

1 file changed

Lines changed: 11 additions & 7 deletions

File tree

src/lib/util/download-queue.ts

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -603,22 +603,26 @@ async function processDownload(item: QueueItem, processId: string): Promise<void
603603
* When a download completes, processQueue() is called again to start the next item
604604
*/
605605
async function processQueue(): Promise<void> {
606-
// CRITICAL: Take queue snapshot BEFORE any await points
607-
// This prevents race conditions where multiple processQueue() calls interleave
608-
const queue = get(queueStore);
609-
const queuedItems = queue.filter((item) => item.status === 'queued');
606+
// Check if there are queued items and initialize pool if needed
607+
// Take initial snapshot just to check if we need to initialize
608+
const initialQueue = get(queueStore);
609+
const hasQueuedItems = initialQueue.some((item) => item.status === 'queued');
610610

611611
// Mark processing as started and register as pool user if we have queued items
612-
if (queuedItems.length > 0 && !processingStarted) {
612+
if (hasQueuedItems && !processingStarted) {
613613
processingStarted = true;
614614
incrementPoolUsers();
615615

616616
// Pre-initialize the pool BEFORE processing any items
617-
// This prevents the race condition where multiple downloads wait for pool initialization
618-
// and then resume in scrambled order
619617
await getFileProcessingPool();
620618
}
621619

620+
// CRITICAL: Re-fetch queue state AFTER any await points
621+
// This prevents race conditions where multiple processQueue() calls interleave
622+
// and process the same item using stale snapshots
623+
const queue = get(queueStore);
624+
const queuedItems = queue.filter((item) => item.status === 'queued');
625+
622626
// Process only the FIRST queued item to preserve ordering
623627
// When it completes, it will call processQueue() again to process the next item
624628
// This ensures downloads complete in the order they were queued

0 commit comments

Comments
 (0)