Store "interrupted by restart" for jobs recovered at boot
CI / ci (push) Successful in 1m27s
CI / ci (pull_request) Successful in 1m28s

Boot recovery now writes the required fixed text to the job error column,
and the recovery test asserts that literal text instead of the constant.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-03 15:16:18 -04:00
co-authored by Claude Opus 5.5
parent f160c9f3a9
commit 985fea6639
2 changed files with 6 additions and 4 deletions
+4 -2
View File
@@ -41,7 +41,9 @@ const (
// Failure codes the runner stores itself. A kind cannot declare them.
const (
// CodeInterrupted is the error of a job a previous process left running.
CodeInterrupted = "interrupted"
// It is fixed framework text, not a snake-case code, so no kind can
// declare it.
CodeInterrupted = "interrupted by restart"
// CodeInternal is the error of a job whose handler failed with anything
// but a *Failure with a code its kind declared, or whose payload or
// result could not be encoded. The underlying error is neither stored
@@ -152,7 +154,7 @@ func Register[P any, R Public](r *Runner, kind string, h Handler[P, R], failureC
if !codePattern.MatchString(code) {
return nil, fmt.Errorf("jobs: register %q: failure code %q is not lower-case snake case", kind, code)
}
if code == CodeInterrupted || code == CodeInternal || code == CodeUnknownKind {
if code == CodeInternal || code == CodeUnknownKind {
return nil, fmt.Errorf("jobs: register %q: failure code %q is reserved for the runner", kind, code)
}
declared[code] = true
+2 -2
View File
@@ -391,8 +391,8 @@ func TestRestartFailsInterruptedJobsAndRunsQueuedOnes(t *testing.T) {
start(t, second)
job := waitFor(t, second, interrupted, finished)
if job.Status != StatusFailed || job.Error == nil || *job.Error != CodeInterrupted {
t.Errorf("interrupted job = %+v, want failed with %q", job, CodeInterrupted)
if job.Status != StatusFailed || job.Error == nil || *job.Error != "interrupted by restart" {
t.Errorf("interrupted job = %+v, want failed with %q", job, "interrupted by restart")
}
if string(job.Result) != `{"done":1}` {
t.Errorf("interrupted job result = %s, want the last partial result kept", job.Result)