fix: remove no-op SaveJobs calls, fix PendingRuns lifecycle and cap

Implements items 4-5 of the whole-project review's suggested order
(docs/PROJECT_REVIEW_PLAN.md):

- Drop the three SaveJobs calls in the run lifecycle (startRunLocked,
  executeRun, SetGlobalPause): none of them change a durable Job field,
  everything they touch lives on JobRuntime, which is never persisted.
  Retire TestStartRunLockedRollbackOnSaveFailure with the rollback it
  guarded, since a run can no longer fail to start this way.
- Clear PendingRuns (the "queue" overlap policy's backlog) when a job is
  disabled or the scheduler is globally paused, so resuming or
  re-enabling a job no longer replays a deferred run left over from
  before the pause/disable. Cap it at maxPendingRuns (10) so a job whose
  runs take longer than its own interval stops accumulating an unbounded
  backlog. Surface the queued count in the details pane via DisplayStats.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-06 17:06:55 +03:00
parent 1242b22e4f
commit 263717874c
9 changed files with 147 additions and 82 deletions
+11 -3
View File
@@ -148,6 +148,10 @@ func (s *Service) SetEnabled(id int, enabled bool) error {
runtime.LastState = "Paused"
runtime.NextRun = "Paused"
runtime.NextDue = time.Time{}
// A disabled job's own occurrences stop firing, so a "queue" backlog it was
// carrying no longer corresponds to anything: clear it rather than replaying
// stale deferred runs if the job is re-enabled later.
runtime.PendingRuns = 0
record = uiRecord(id, job.Name, "Paused", "Job was disabled")
}
prependLog(runtime, record)
@@ -175,12 +179,16 @@ func (s *Service) SetGlobalPause(paused bool) error {
for index := range s.jobs {
job := &s.jobs[index]
runtime := s.runtimeForLocked(job)
if paused {
// A "queue" backlog counts occurrences missed *while paused is off*; once
// paused, none of those correspond to anything the user would expect
// replayed on resume, so drop it rather than letting a stale counter fire
// a deferred run for an occurrence from before the pause.
runtime.PendingRuns = 0
}
s.refreshNextRunFromLocked(job, runtime, now)
}
err := s.store.SaveConfig()
if err == nil {
err = s.store.SaveJobs(s.jobs)
}
s.mu.Unlock()
if err != nil {