@@ -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 */
605605async 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