failed() marked the latest running execution of the server as failed.
A manual run that never started, or a run that timed out, could mark a
different running cleanup as failed.
- Keep the execution id in the cache under the queue job uuid, because
failed() runs on a fresh copy of the job
- Change nothing when the job created no execution
A manual cleanup that started while a stop-triggered cleanup held the
server lock was dropped. The UI said it was queued, but it never ran.
- Release a manual run and try again after 60 seconds
- Stop the retries 780 seconds after dispatch (the lock expiry plus a
margin)
- Scheduled and stop-triggered runs are still dropped
Scheduled, manual and stop-triggered cleanups share one per-server lock.
Stop-triggered cleanups wait 60 seconds and are coalesced per server, so
a bulk stop queues one cleanup. Remote commands share a 540 second
deadline below the 600 second job timeout, and application images are
scanned with a fixed number of remote commands.
Add database-backed schedule states and deliveries so distributed schedulers publish each occurrence once, queue jobs claim executions atomically, and stale occurrences are cleaned up.
Implements getPreviousRunDate() + cache-based tracking in shouldRunNow()
to prevent duplicate dispatch of scheduled jobs when queue delays push
execution past the cron minute. This resilience ensures jobs catch missed
windows without double-dispatching within the same cron window.
Updated scheduled job dispatches to include dedupKey parameter:
- Docker cleanup operations
- Server connection checks
- Sentinel restart checks
- Server storage checks
- Server patch checks
DockerCleanupJob now dispatches on the 'high' queue for faster processing.
Includes comprehensive test coverage for dedup behavior across different
cron schedules and delay scenarios.
- Implement pagination for skipped jobs display with 20 items per page
- Add pagination controls (previous/next buttons) to the scheduled jobs view
- Exclude ScheduledJobManager "started" events from run logs, keeping only "completed" events
- Add ShouldBeEncrypted interface to ScheduledTaskJob for secure queue handling
- Update log filtering to fetch 500 recent skips and slice for pagination
- Use Log facade instead of fully qualified class name