diff --git a/static/js/cookbookRunning.js b/static/js/cookbookRunning.js index 36e93bb..5f75a49 100644 --- a/static/js/cookbookRunning.js +++ b/static/js/cookbookRunning.js @@ -2266,6 +2266,10 @@ export function _renderRunningTab() { // Wire stop el.querySelector('.cookbook-task-action-stop').addEventListener('click', async () => { + // Abort the reconnect loop before sending kill so that a DOWNLOAD_FAILED + // marker written by the shell wrapper (on SIGINT/non-zero exit) cannot + // trigger an auto-retry after a manual stop. + if (el._abort) el._abort.abort(); const badge = el.querySelector('.cookbook-task-status'); if (badge) { badge.textContent = 'stopping...'; badge.className = 'cookbook-task-status cookbook-task-stopping'; } el.dataset.status = 'stopped'; @@ -2762,7 +2766,7 @@ async function _reconnectTask(el, task) { const _accessDenied = /Access to model.*is restricted|gated repo|GatedRepoError|401 Unauthorized|403 Forbidden|not in the authorized list|awaiting a review|must (?:be authenticated|have access)/i.test(snapshot); const _dlKey = task.payload?.repo_id || task.name; const _dlN = _dlRetryCount.get(_dlKey) || 0; - if (!_accessDenied && !task._userStopped && task.type === 'download' && task.payload && _dlN < _DL_MAX_AUTO_RETRY) { + if (!controller.signal.aborted && !_accessDenied && task.type === 'download' && task.payload && _dlN < _DL_MAX_AUTO_RETRY) { // Auto-retry: kill the dead session and re-launch (resumes from // the cached .incomplete files) after a short delay. _dlRetryCount.set(_dlKey, _dlN + 1);