cmd/moveprobe: after-write exits non-zero when its bg row does not commit
The row is the mode's whole promise (the known row a dirty rollback must bring back), so a failed insert stops startup with the reason on stderr instead of logging and failing readiness without it. Review fix round 1, item 2.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2 files changed,
+32
−1
cmd/moveprobe/main.go+4 −1cmd/moveprobe/main_test.go+28 −0
diff --git a/cmd/moveprobe/main.go b/cmd/moveprobe/main.go| index f57355d77..04a96b6e6 100644 |
| --- a/cmd/moveprobe/main.go |
| +++ b/cmd/moveprobe/main.go |
| @@ -157,8 +157,11 @@ func run(args []string) int { |
| loopCtx, stopLoop := context.WithCancel(ctx) |
| defer stopLoop() |
| if mode == modeAfterWrite { |
| + // The mode's whole promise is this row; without it the rollback |
| + // would have nothing to find, so the app does not start. |
| if err := a.insertSeq("bg"); err != nil { |
| - logf("after-write: the bg row: %v", err) |
| + logf("after-write: the bg row did not commit: %v", err) |
| + return 1 |
| } |
| } else { |
| go a.bgLoop(loopCtx) |
diff --git a/cmd/moveprobe/main_test.go b/cmd/moveprobe/main_test.go| index 53193e14d..74d365063 100644 |
| --- a/cmd/moveprobe/main_test.go |
| +++ b/cmd/moveprobe/main_test.go |
| @@ -1076,3 +1076,31 @@ func TestWorkerWriteFailuresFailReady(t *testing.T) { |
| } |
| p.stop() |
| } |
| + |
| +func TestAfterWriteExitsWhenItsRowFails(t *testing.T) { |
| + f := newFixture(t) |
| + seed := f.start(f.env) |
| + seed.wait("/ready", http.StatusOK) |
| + seed.stop() |
| + killWorkers(f.db) |
| + |
| + failInserts(t, f.db, "bg") |
| + p := f.start(f.envWith(map[string]string{"CARLOS_REGION": "ie", "MOVEPROBE_FAIL_READY_IN": "ie,after-write"})) |
| + select { |
| + case <-p.done: |
| + case <-time.After(15 * time.Second): |
| + t.Fatalf("after-write kept running without its bg row; output:\n%s", p.out) |
| + } |
| + if code := p.cmd.ProcessState.ExitCode(); code == 0 { |
| + t.Errorf("after-write exited 0 without its bg row; output:\n%s", p.out) |
| + } |
| + if !strings.Contains(p.out.String(), "forced bg failure") { |
| + t.Errorf("the exit does not say why; output:\n%s", p.out) |
| + } |
| + if w := workerPIDs(f.db); len(w) != 0 { |
| + t.Errorf("after-write forked a worker before its row committed: %v", w) |
| + } |
| + if n := countRows(t, f.db, "bg", "ie"); n != 0 { |
| + t.Errorf("%d bg rows in ie", n) |
| + } |
| +} |