domain/config.go + app: persist global pause state across restarts (T4.1, T4.2)
Add Config.Paused bool so the scheduler's paused flag survives a restart. SetGlobalPause now writes the flag into store.Config and calls SaveConfig; NewService seeds s.paused from Config.Paused before computing first next-run times, so jobs show "Scheduler paused" immediately at startup when paused. Also add Paused to the yamlConfig shadow struct to keep the direct conversion from domain.Config valid until the YAML import path is dropped in T6.3. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -152,13 +152,17 @@ func (s *Service) SetEnabled(id int, enabled bool) error {
|
|||||||
func (s *Service) SetGlobalPause(paused bool) error {
|
func (s *Service) SetGlobalPause(paused bool) error {
|
||||||
s.mu.Lock()
|
s.mu.Lock()
|
||||||
s.paused = paused
|
s.paused = paused
|
||||||
|
s.store.Config.Paused = paused
|
||||||
now := time.Now()
|
now := time.Now()
|
||||||
for index := range s.jobs {
|
for index := range s.jobs {
|
||||||
job := &s.jobs[index]
|
job := &s.jobs[index]
|
||||||
runtime := s.runtimeForLocked(job)
|
runtime := s.runtimeForLocked(job)
|
||||||
s.refreshNextRunFromLocked(job, runtime, now)
|
s.refreshNextRunFromLocked(job, runtime, now)
|
||||||
}
|
}
|
||||||
err := s.store.SaveJobs(s.jobs)
|
err := s.store.SaveConfig()
|
||||||
|
if err == nil {
|
||||||
|
err = s.store.SaveJobs(s.jobs)
|
||||||
|
}
|
||||||
s.mu.Unlock()
|
s.mu.Unlock()
|
||||||
|
|
||||||
state, detail := "Resumed", "All job execution resumed"
|
state, detail := "Resumed", "All job execution resumed"
|
||||||
|
|||||||
@@ -82,6 +82,7 @@ func NewService(store *storage.Store, jobs []domain.Job) *Service {
|
|||||||
schedules: make(map[int]domain.Schedule, len(jobs)),
|
schedules: make(map[int]domain.Schedule, len(jobs)),
|
||||||
runJob: runner.RunJob,
|
runJob: runner.RunJob,
|
||||||
ctx: context.Background(),
|
ctx: context.Background(),
|
||||||
|
paused: store.Config.Paused,
|
||||||
}
|
}
|
||||||
// Parse every schedule once, then compute each job's first next-run so the
|
// Parse every schedule once, then compute each job's first next-run so the
|
||||||
// Service is ready to schedule the moment it exists — mirroring the old
|
// Service is ready to schedule the moment it exists — mirroring the old
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ type Config struct {
|
|||||||
NotifyOnFailure bool `json:"notify_on_failure,omitempty"`
|
NotifyOnFailure bool `json:"notify_on_failure,omitempty"`
|
||||||
ExecutionMode ExecutionMode `json:"execution_mode,omitempty"`
|
ExecutionMode ExecutionMode `json:"execution_mode,omitempty"`
|
||||||
OverlapPolicy OverlapPolicy `json:"overlap_policy,omitempty"`
|
OverlapPolicy OverlapPolicy `json:"overlap_policy,omitempty"`
|
||||||
|
Paused bool `json:"paused,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// JobsFile is the on-disk shape of jobs.json. Wrapping the slice in a top-level
|
// JobsFile is the on-disk shape of jobs.json. Wrapping the slice in a top-level
|
||||||
|
|||||||
@@ -24,15 +24,16 @@ type Store struct {
|
|||||||
// domain struct so the value conversions in importYAMLConfig / importYAMLJobs
|
// domain struct so the value conversions in importYAMLConfig / importYAMLJobs
|
||||||
// remain valid.
|
// remain valid.
|
||||||
type yamlConfig struct {
|
type yamlConfig struct {
|
||||||
JobsDir string `yaml:"jobs_dir"`
|
JobsDir string `yaml:"jobs_dir"`
|
||||||
LogsDir string `yaml:"logs_dir"`
|
LogsDir string `yaml:"logs_dir"`
|
||||||
MaxLogFiles int `yaml:"max_log_files"`
|
MaxLogFiles int `yaml:"max_log_files"`
|
||||||
MaxLogAgeDays int `yaml:"max_log_age_days"`
|
MaxLogAgeDays int `yaml:"max_log_age_days"`
|
||||||
StartOnLogin bool `yaml:"start_on_login,omitempty"`
|
StartOnLogin bool `yaml:"start_on_login,omitempty"`
|
||||||
KeepRunningInTray bool `yaml:"keep_running_in_tray,omitempty"`
|
KeepRunningInTray bool `yaml:"keep_running_in_tray,omitempty"`
|
||||||
NotifyOnFailure bool `yaml:"notify_on_failure,omitempty"`
|
NotifyOnFailure bool `yaml:"notify_on_failure,omitempty"`
|
||||||
ExecutionMode domain.ExecutionMode `yaml:"execution_mode,omitempty"`
|
ExecutionMode domain.ExecutionMode `yaml:"execution_mode,omitempty"`
|
||||||
OverlapPolicy domain.OverlapPolicy `yaml:"overlap_policy,omitempty"`
|
OverlapPolicy domain.OverlapPolicy `yaml:"overlap_policy,omitempty"`
|
||||||
|
Paused bool `yaml:"paused,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type yamlJob struct {
|
type yamlJob struct {
|
||||||
|
|||||||
Reference in New Issue
Block a user