From aede7dd0895c5984ed126dd7eff5719565d2cebd Mon Sep 17 00:00:00 2001 From: Broque Thomas <26755000+Nezreka@users.noreply.github.com> Date: Fri, 17 Apr 2026 15:01:45 -0700 Subject: [PATCH] Fix download modal freezing by moving M3U save to completion only MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit autoSavePlaylistM3U was called on every 2-second poll cycle once any track completed, flooding the server with heavyweight M3U generation requests (fuzzy matching all tracks against the DB). This exhausted Flask's thread pool, causing the batch status endpoint to hang and killing the poller — making the modal freeze mid-download. Now fires once when the batch completes instead of on every poll. --- webui/static/script.js | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/webui/static/script.js b/webui/static/script.js index b8adeb6f..f314696a 100644 --- a/webui/static/script.js +++ b/webui/static/script.js @@ -15658,10 +15658,10 @@ function processModalStatusUpdate(playlistId, data) { document.getElementById(`download-progress-text-${playlistId}`).textContent = `${completedCount}/${missingCount} completed (${progressPercent.toFixed(0)}%)`; document.getElementById(`stat-downloaded-${playlistId}`).textContent = completedCount; - // Auto-save M3U file for playlists as downloads progress - if (completedCount > 0) { - autoSavePlaylistM3U(playlistId); - } + // Auto-save M3U file once when all downloads finish (not on every poll cycle). + // Previously this fired on EVERY 2-second poll when completedCount > 0, flooding + // the server with heavyweight M3U generation requests that exhausted Flask threads + // and caused the batch status endpoint to hang — killing the poller. // CLIENT-SIDE COMPLETION: Only complete when ALL task rows in the UI reflect a terminal state. // Using totalFinished (derived from DOM updates in THIS render pass) prevents premature @@ -15678,6 +15678,11 @@ function processModalStatusUpdate(playlistId, data) { process.status = 'complete'; updatePlaylistCardUI(playlistId); + // Save M3U once on completion (not during progress polling) + if (completedCount > 0) { + autoSavePlaylistM3U(playlistId); + } + // Show the force download toggle again const forceToggleContainer = document.querySelector(`#force-download-all-${playlistId}`)?.closest('.force-download-toggle-container'); if (forceToggleContainer) {