refactor(schedule): make processor restartable (4/9) - #783
Conversation
🔐 Codex Security Review
Review SummaryOverall Risk: NONE FindingsNo security, correctness, or reliability findings identified in the changed hunks. NotesReviewed Tests were not run in this read-only review environment. Generated by Codex Security Review | |
83f3395 to
5ad0b87
Compare
- begin asynchronous processor cleanup when activation is canceled - cover restart after cancellation and drain
There was a problem hiding this comment.
Pull request overview
Refactors the schedule processor to implement the shared runtimejobs.Lifecycle contract so it can be started, stopped/drained, and started again without rebuilding fleetd, as groundwork for future active/passive activation control.
Changes:
- Make
schedule.Processorrestartable by introducing explicit lifecycle state, per-activation cron/job tracking, and context-awareStart(ctx)/Stop(ctx). - Update
fleetdto stop the schedule processor via the shared bounded standalone stop helper. - Expand schedule processor tests to cover deadline-bounded stop, activation-cancellation behavior, and restart semantics.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
server/internal/domain/schedule/processor.go |
Implements runtimejobs.Lifecycle for the schedule processor, including activation-scoped state and stop/drain logic. |
server/internal/domain/schedule/processor_test.go |
Updates tests for the new Stop(context.Context) API and adds coverage for restart/drain/cancellation cases. |
server/cmd/fleetd/main.go |
Switches schedule processor shutdown to stopStandaloneJob(...) to preserve bounded shutdown behavior. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 8513c9b462
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: a39dd8ae89
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
- reject restart while a canceled activation is draining - fence cancellation watchers to their originating activation - cover both handoff races with deterministic tests
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 80de634ce7
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
- keep post-claim state writes alive after activation cancellation - bound each finalization and repair attempt - cover cancellation immediately after successful dispatch
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 88f26c96ff
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
Separate admission cancellation from admitted work so graceful stop drains a schedule through dispatch and final persistence. Keep startup outside the lifecycle lock and force-cancel work only when Stop exhausts its caller deadline.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 3553efeb38
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
Make concurrent Start callers wait for the published activation's startup result while preserving cancellation and deadline-bounded Stop behavior.
Reviewable diff: +152/-84 across 2 files (excludes generated, test, and story files).
Summary
Schedule processing can now be stopped, fully drained, and started again without rebuilding
fleetd. This prepares scheduled command recovery, cron callbacks, and end-of-window reverts for active/passive demotion and promotion while preserving standalone behavior.Stack:
fleetdcutover: #788This PR targets
mainand builds on theruntimejobs.Lifecyclecontract merged in #780. The sibling domain refactors can merge independently; #788 performs the final catalog/cutover integration. Passive-mode coordinator wiring, epoch fencing, and request gating remain later HA work.How it works
Each
Startcreates one schedule activation with two phases. Its admission context is canceled immediately when ownership is withdrawn orStopbegins, preventing loops, timers, and cron from starting new work. Work already admitted keeps a separate activation-owned context through target resolution, command dispatch, and final database state persistence, so a demotion cannot strand a schedule halfway through its workflow.Stop(ctx)waits for admitted work to drain. If the caller's shutdown deadline expires, it cancels that work context and returns the deadline error; the processor remains unavailable for restart until the old activation has actually exited. Startup database work runs outside the lifecycle lock, allowingStopto honor its own deadline even when startup is blocked.flowchart LR S["Start activation"] --> R["Recover and register schedules"] R --> A["Admit timer, cron, and reconciliation work"] A --> W["Run schedule workflow"] W --> D["Dispatch command"] D --> P["Persist final schedule state"] X["Activation canceled or Stop called"] --> C["Close admission"] C --> G["Drain admitted work"] G --> N["Allow next activation"] T["Stop deadline expires"] --> F["Force-cancel admitted work"] F --> NstateDiagram-v2 [*] --> Starting Starting --> Running: recovery succeeds Starting --> Draining: startup fails or is canceled Running --> Draining: activation canceled or Stop called Draining --> Stopped: callbacks and timers exit Draining --> Draining: Stop deadline force-cancels work Stopped --> Starting: next StartAreas of the code involved
server/internal/domain/schedule/processor.goserver/cmd/fleetd/main.goKey technical decisions & trade-offs
Stopdeadline decide when graceful draining becomes forced cancellation rather than embedding another processor-specific timeout.Related
Related: #740
Testing & validation
go test -short -race -count=1 ./internal/domain/schedule ./cmd/fleetdgolangci-lintpassed for./internal/domain/schedule/...and./cmd/fleetd/....Post-Deploy Monitoring & Validation
Watch schedule recovery/start errors, command creation from due schedules, end-of-window reverts, and shutdown drain logs through at least one schedule interval. Roll back if schedules are duplicated, due work stops dispatching, reverts are missed, or processor drains repeatedly exceed the shutdown budget.