fix(scheduler): harden scheduled operations with stale cleanup, cron validation, and design fixes (#549)

* fix(scheduler): clean up stale runs on startup and auto-disable invalid cron tasks

- Add markStaleRunsAsFailed() bulk DB method with status index
- Clean up orphaned 'running' records on scheduler startup
- Auto-disable tasks when cron expression becomes invalid at execution time
- Promote CRUD debug logs to standard logs for scheduled task admin actions
- Add diagnostic logging for task pre-checks, action timing, and prune fallback

* refactor(scheduling): extract shared types and fix design system violations

- Extract ScheduledTask, TaskRun, NodeOption to shared types file
- Extract getCronDescription and formatTimestamp to shared utilities
- Fix formatTimestamp falsy-zero null check
- Tighten last_status type to 'success' | 'failure' | null
- Add strokeWidth={1.5} to all action icons per design system
- Add sr-only DialogDescription for accessibility
- Wrap Sheet run history in ScrollArea
- Fix delete button styling to match design system pattern
- Change manual trigger toast from "executed" to "triggered"

* test(scheduler): add tests for snapshot, remote update, stale cleanup, and cron invalidation

- Add stale run cleanup tests (bulk markStaleRunsAsFailed, logging)
- Add cron invalidation test (auto-disable, error message)
- Add executeSnapshot tests (fleet capture, empty stacks)
- Add executeUpdateRemote tests (proxy success, remote error)
- Document stale run cleanup and cron auto-disable in troubleshooting docs
This commit is contained in:
Anso
2026-04-13 11:32:09 -04:00
committed by GitHub
parent 7334658927
commit 44e8fdfba9
10 changed files with 368 additions and 121 deletions
+12
View File
@@ -180,3 +180,15 @@ Check that the target stack exists and has at least one running container. For w
### "Run Now" finishes instantly
This is expected behavior. The Run Now button triggers the update check in the background and returns immediately. The actual check runs asynchronously; check the run history panel to see the result once it completes.
### Policy was automatically disabled
If a policy's cron expression becomes invalid after creation, the scheduler disables the policy and records the reason in the status column. To fix this:
1. Open the policy in edit mode.
2. Re-enter a valid cron expression (or choose a preset).
3. Re-enable the policy using the toggle switch.
### Run shows "Server restarted during execution"
This means Sencho was restarted while this policy's update check was mid-execution. The run was marked as failed automatically on startup. The policy itself is still enabled and will run at its next scheduled time. Use **Run Now** if you want to trigger it immediately.
+16
View File
@@ -166,3 +166,19 @@ The Scheduler Service runs in the background and checks for due tasks every 60 s
5. The next run time is recalculated from the cron expression.
If a task is still running from a previous execution, the scheduler skips it to prevent overlap.
If the server restarts while a task is mid-execution, the orphaned run record is automatically marked as failed with a "Server restarted during execution" message on the next startup. No manual cleanup is needed.
## Troubleshooting
### Task was automatically disabled
If a task's cron expression becomes invalid after creation (for example, due to a corrupt database edit or an expression that was valid in a previous version), the scheduler disables the task and records the reason in the last error column. To fix this:
1. Open the task in edit mode.
2. Re-enter a valid cron expression.
3. Re-enable the task using the toggle switch.
### Run shows "Server restarted during execution"
This means Sencho was restarted (or crashed) while this task was mid-execution. The run was marked as failed automatically on startup. The task itself is still enabled and will run at its next scheduled time. If you want to re-run it immediately, use the **Run Now** button.