schedule, host: flag-off behaviour identical to main (Opus review M1, M2)
The schedule runner runs on context.Background() as before, so an agent shutdown never cancels an in-flight delivery; with the flag off, a failed fire record still sends the member-facing fire event (hostwrite.Legacy tells the pass-through work apart). The I1, I2, I3 and M5 findings are Plan 6b's.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
3 files changed,
+13
−2
internal/host/agent.go+1 −1internal/hostwrite/write.go+7 −0internal/schedule/runner.go+5 −1
CI passed — run details
diff --git a/internal/host/agent.go b/internal/host/agent.go| index 6422cd6d4..04bf121e8 100644 |
| --- a/internal/host/agent.go |
| +++ b/internal/host/agent.go |
| @@ -518,7 +518,7 @@ func runAgent(args []string, buildClaims ClaimFactory) { |
| log.Fatalf("agent: host claims: %v", err) |
| } |
| if sd != nil { |
| - sd.runner.Start(agentCtx) |
| + sd.runner.Start(context.Background()) // runs until the process ends, like every loop below |
| } |
| serialClaims := make(chan struct{}, 1) |
| if err := claims.startRegional(agentCtx, serialClaims, func(err error) { log.Printf("agent: regional claims: %v", err) }); err != nil { |
diff --git a/internal/hostwrite/write.go b/internal/hostwrite/write.go| index dc9b3c097..8b9183347 100644 |
| --- a/internal/hostwrite/write.go |
| +++ b/internal/hostwrite/write.go |
| @@ -42,4 +42,11 @@ func (c Config) Select(ctx context.Context, host, action string) (Work, error) { |
| type legacy struct{} |
| +// Legacy reports whether w is the flag-off pass-through work, so callers |
| +// can keep their exact pre-claim behaviour when the flag is unset. |
| +func Legacy(w Work) bool { |
| + _, ok := w.(legacy) |
| + return ok |
| +} |
| + |
| func (legacy) With(_ context.Context, _ Identity, fn func() error) error { return fn() } |
diff --git a/internal/schedule/runner.go b/internal/schedule/runner.go| index eb964d164..23b3594d1 100644 |
| --- a/internal/schedule/runner.go |
| +++ b/internal/schedule/runner.go |
| @@ -470,7 +470,11 @@ func (r *Runner) record(ctx context.Context, rt registry.Route, t registry.Timer |
| }) |
| if err != nil { |
| log.Printf("schedule: %s/%s: record fire: %v", rt.Host, t.Name, err) |
| - return |
| + // Flag off keeps the old behaviour: the fire event still goes out. |
| + // Under the claim, a refused or failed guarded write stops here. |
| + if selected, ok := ctx.Value(timerWorkKey{}).(timerWork); !ok || !hostwrite.Legacy(selected.work) { |
| + return |
| + } |
| } |
| if r.Event != nil { |
| msg := fmt.Sprintf("schedule %s fired POST %s → %s in %s", t.Name, t.Path, status, took.Truncate(time.Millisecond)) |