git-ents.gitmain
⌘K
foforge
commit e5e8780
fix: stop live check view from reload-looping when result is stale

The poller signalled done whenever the in-memory live buffer was gone, even if the persisted result still read queued/running (the worker had not caught up yet). The reloaded page picked the live view again and polled straight back into done, reloading forever. Add a stale state that reports the mismatch without reloading.

Assisted-by: Claude:claude-sonnet-5

Joseph D. Carpinelli · 1 month ago

Reviews

No reviews of this commit yet — record a verdict below.

Start a review

verdict

crates/git-ents-server/src/web/live.js @@ -3,14 +3,21 @@ const poll = () => { fetch(url, { cache: 'no-store' }) .then((response) => { - if (response.headers.get('X-Check-Live') === 'done') { - window.location.reload(); - return null; - } - return response.text(); + const state = response.headers.get('X-Check-Live'); + return response.text().then((html) => ({ state, html })); }) - .then((html) => { - if (html === null) return; + .then(({ state, html }) => { + if (state === 'done') { + window.location.reload(); + return; + } + if (state === 'stale') { + container.insertAdjacentHTML( + 'beforeend', + '<p class="shell-note">No live output available right now; this check is still marked in progress.</p>' + ); + return; + } container.innerHTML = html; setTimeout(poll, 1000); })
crates/git-ents-server/src/web/pages.rs @@ -1064,11 +1064,14 @@ } /// One poll of a running check's live output — the fragment [`LIVE_SCRIPT`] -/// swaps into the run page's `#live-terminal` container. Signals completion -/// (the check no longer has a live buffer: it settled, or was never queued) -/// via the `X-Check-Live: done` response header rather than the body, so the -/// script can tell a finished check apart from one that simply has no output -/// yet. +/// swaps into the run page's `#live-terminal` container. Reports its state via +/// the `X-Check-Live` response header rather than the body, so the script can +/// tell the three cases apart: `running` (a live buffer exists), `done` (no +/// live buffer, and the persisted result has actually settled), or `stale` (no +/// live buffer, but the persisted result still reads queued/running — the +/// worker hasn't caught up yet). Reporting `done` in the `stale` case is what +/// used to send the script into a reload loop, since the reloaded page would +/// still pick the live branch and poll straight back into "done". /// /// [`LIVE_SCRIPT`]: super::assets::LIVE_SCRIPT pub(super) async fn check_live_fragment( @@ -1082,9 +1085,15 @@ }; let key = (repo.to_owned(), commit_oid, name.to_owned()); let recording = git_effect::engine::live_snapshot(live_runs, &key); - let done = recording.is_none(); + let header = if recording.is_some() { + "running" + } else { + match latest_outcome(repo, commit_oid, name).await { + Some(outcome) if super::render::is_in_progress(outcome.status) => "stale", + _ => "done", + } + }; let body = super::render::live_fragment_body(recording).into_string(); - let header = if done { "done" } else { "running" }; ([("x-check-live", header)], body).into_response() }