mirror of
https://github.com/pewdiepie-archdaemon/odysseus.git
synced 2026-06-15 17:25:26 -04:00
fix(cookbook): recover completed downloads from DOWNLOAD_OK in background reconciler (#4000)
The dashboard background status reconciler (_pollBackgroundStatus) only recovered "done" for dependency installs when the backend reported a finished task as "stopped". A real model download whose tmux pane is gone after DOWNLOAD_OK (so the dead-session check misses the landed snapshot) fell through to `task.type === 'download' ? 'crashed'`, so a completed download was shown as crashed (and stalled on the Serve tab). Recover "done" from the terminal DOWNLOAD_OK sentinel, mirroring the dep-install recovery already present. The background poll runs blind, so it keys off the conclusive exit-0 sentinel only — not the `/snapshots/` path, which can be printed mid-stream for multi-file downloads and would risk marking an incomplete download done. Fixes #3897 Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -3533,12 +3533,22 @@ async function _pollBackgroundStatus() {
|
||||
// dead-session check inspects). Recover "done" from the retained output's
|
||||
// exit-0 sentinel so a clean install isn't downgraded to crashed.
|
||||
const depDone = !!task.payload?._dep && _depInstallSucceeded(task.output);
|
||||
// A finished model download whose tmux pane is gone is also reported
|
||||
// "stopped" (the dead-session check can miss the landed snapshot).
|
||||
// Recover "done" from the terminal `DOWNLOAD_OK` sentinel — emitted
|
||||
// only after the runner exits 0 — so a completed download isn't
|
||||
// downgraded to crashed. This background poll runs blind (no live
|
||||
// stream to debounce against), so unlike the reconnect loop it keys
|
||||
// off the conclusive exit sentinel only, never the `/snapshots/` path,
|
||||
// which can be printed mid-stream for multi-file downloads.
|
||||
const downloadDone = task.type === 'download'
|
||||
&& String(task.output || '').includes('DOWNLOAD_OK');
|
||||
const nextStatus = live.status === 'completed'
|
||||
? 'done'
|
||||
: (live.status === 'error'
|
||||
? 'error'
|
||||
: (live.status === 'stopped'
|
||||
? (depDone ? 'done' : (task.type === 'download' ? 'crashed' : 'stopped'))
|
||||
? ((depDone || downloadDone) ? 'done' : (task.type === 'download' ? 'crashed' : 'stopped'))
|
||||
: null));
|
||||
if (nextStatus && task.status !== nextStatus) {
|
||||
updates.status = nextStatus;
|
||||
|
||||
@@ -74,7 +74,23 @@ def test_background_poll_recovers_done_for_stopped_dependency_install():
|
||||
source = _read("static/js/cookbookRunning.js")
|
||||
|
||||
assert "const depDone = !!task.payload?._dep && _depInstallSucceeded(task.output);" in source
|
||||
assert "depDone ? 'done' : (task.type === 'download' ? 'crashed' : 'stopped')" in source
|
||||
assert "(depDone || downloadDone) ? 'done' : (task.type === 'download' ? 'crashed' : 'stopped')" in source
|
||||
|
||||
|
||||
def test_background_poll_recovers_done_for_completed_download():
|
||||
"""When the backend reports a finished model download as "stopped" (its
|
||||
tmux pane is gone after DOWNLOAD_OK, so the dead-session check can miss the
|
||||
landed snapshot), the reconciler must recover "done" from the terminal
|
||||
DOWNLOAD_OK sentinel instead of downgrading the card to crashed. The
|
||||
background poll keys off DOWNLOAD_OK only (not the "/snapshots/" path, which
|
||||
can appear mid-stream for multi-file downloads)."""
|
||||
source = _read("static/js/cookbookRunning.js")
|
||||
|
||||
normalized = " ".join(source.split())
|
||||
assert (
|
||||
"const downloadDone = task.type === 'download' "
|
||||
"&& String(task.output || '').includes('DOWNLOAD_OK');"
|
||||
) in normalized
|
||||
|
||||
|
||||
def test_dependency_install_payload_keeps_env_path_for_refresh():
|
||||
|
||||
Reference in New Issue
Block a user