Skip to content

fix(admin): tell a hung art build from an interrupted one, and say why a build waits - #85

Merged
plainprogrammer merged 12 commits into
mainfrom
079-art-index-stalled-and-retry-reason
Oct 14, 2026
Merged

plainprogrammer merged 12 commits into
mainfrom
079-art-index-stalled-and-retry-reason

Conversation

@plainprogrammer

Copy link
Copy Markdown
Owner

The art index panel on /admin/catalog now tells a hung build from an interrupted one, and says why and until when a build waits to retry.

Closes #79
Closes #80

What changed

  • A hung art build reads "Interrupted" with a disabled button #79, a hung build. A running build whose heartbeat is over 10 minutes old while a worker still holds its job is stalled (MTG::ArtBuild#stalled?), not interrupted. The panel says it is building with no heartbeat for N minutes and what a restart does, instead of "Build it again" beside a disabled button. The button stays disabled, the page keeps polling and there is no failed-job link, as for a stalled refresh. A stale build whose job has failed or gone still reads "Interrupted", as PR fix(admin): show a crashed art build as interrupted at once #75 made it. catalog:status says the same.
  • Art index panel hides the reason and time while its retry waits #80, a waiting retry. When the latest build failed and its own job is scheduled to run again, the panel reads "Queued to retry. The last build failed: …" with a "Retrying at" fact for that job. A build queued fresh still reads "Queued."
  • One core change. Catalog::Operation::Queue#retry_at takes an optional job id, so a failure is given as the reason only for that build's own retry. It names no collectible; the refresh's use is unchanged.
  • No view, CSS or helper change: the panel renders what the operation returns.
  • Spec 015 (1.3.0: AC-4.11, AC-4.12, glossary, Error Scenarios), spec 011 (1.2.1), CLAUDE.md and docs/design-system/components/AdminCatalog.md match.

Decisions for you

  1. The stalled wording gives advice ("restart the app") where the refresh's stalled line gives none. Issue A hung art build reads "Interrupted" with a disabled button #79 asked that it say what the admin can do. It says both outcomes of a restart: the build carries on, or reads interrupted and can be built again.
  2. The retry reason is tied to the build's own job id, which is stricter than the refresh's rule (any failed run plus any scheduled job). The refresh was left alone.

Verification

  • bin/ci: passed on the final commit (the pre-push run).
  • New examples at model, operation, request and rake level, each seen failing first.
  • One independent read-only review (Opus): no must-fix. It ran Solid Queue 1.7.0 in fork mode with a job hung in sleep: on a graceful stop the job went back to ready in 5 of 5 runs, so the re-run carries on. Its follow-ups (the wording after a hard kill, the retry time taken from the build's own job, one more case, two comments) are the last five commits.
  • Not verified: a thread stuck in a C call, a real hung build on a live instance, and the panel in a browser (no markup changed; only the summary text and facts).

Known limits and follow-ups

🤖 Generated with Claude Code

plainprogrammer and others added 12 commits October 13, 2026 18:38
…s job (#79)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A build whose heartbeat is over 10 minutes old while a worker still holds
its job read "Interrupted. Build it again…" beside a disabled button. It
now reads as building with no heartbeat for N minutes and says to restart
the app, as a stalled refresh reads as running. The button stays disabled,
the page keeps polling and no failed-job link shows, as for the refresh.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… does (#79)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
While a failed build's own job waited in the queue to run again (a rate
limit, a busy database), the art index read plain "Queued.". It now reads
"Queued to retry. The last build failed: …" with a "Retrying at" fact, as
the refresh does. A build queued fresh, or by another job, stays "Queued.".

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
, #80)

Spec 015 goes to 1.3.0 (glossary, AC-4.1, AC-4.10, new AC-4.11 and AC-4.12,
FR-2, Error Scenarios) and spec 011 to 1.2.1 (AC-3.11's art line).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…kill too (#79)

A graceful restart releases the held job and the build carries on. After a
crash or a kill the job stays held until its process is pruned, and the
build then reads interrupted. The summary and the status line say both.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
"Retrying at" took the earliest scheduled build job, which could be another
job's while the reason was the failed build's own.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ob is held (#79)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…the art line say

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ll (#79)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@plainprogrammer plainprogrammer self-assigned this Oct 14, 2026
@plainprogrammer
plainprogrammer merged commit fe278f2 into main Oct 14, 2026
5 of 6 checks passed
@plainprogrammer
plainprogrammer deleted the 079-art-index-stalled-and-retry-reason branch October 14, 2026 02:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Art index panel hides the reason and time while its retry waits A hung art build reads "Interrupted" with a disabled button

1 participant