T1.4: Create src/scheduler; move scheduler logic

Move scheduler.go and scheduler_test.go from src/core to the new
src/scheduler package. The scheduler still takes *[]domain.Job and
*core.Store (storage moves in T1.5). Update src/gui/app.go to import
the new package; rename the local variable to sched to avoid shadowing
the scheduler package name.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
mixeme
2026-06-18 22:03:16 +03:00
parent c29d581fb1
commit ad0e45a7dd
4 changed files with 21 additions and 19 deletions
+15 -14
View File
@@ -16,6 +16,7 @@ import (
"gitea.mixdep.ru/mix/gosentry/src/core"
"gitea.mixdep.ru/mix/gosentry/src/domain"
"gitea.mixdep.ru/mix/gosentry/src/runner"
"gitea.mixdep.ru/mix/gosentry/src/scheduler"
"fyne.io/fyne/v2"
"fyne.io/fyne/v2/app"
@@ -263,7 +264,7 @@ func newMainView(w fyne.Window) (fyne.CanvasObject, func(time.Duration, bool)) {
jobLogs.Refresh()
history.Refresh()
}
var scheduler *core.Scheduler
var sched *scheduler.Scheduler
list := widget.NewList(
func() int { return len(filteredJobs) },
@@ -353,8 +354,8 @@ func newMainView(w fyne.Window) (fyne.CanvasObject, func(time.Duration, bool)) {
updated := newEvent(saved.ID, saved.Name, "Updated", "Job settings changed")
jobs[selected].Logs = append([]event{updated}, jobs[selected].Logs...)
events = append(events, updated)
if scheduler != nil {
scheduler.RefreshSchedule(selected)
if sched != nil {
sched.RefreshSchedule(selected)
}
_ = store.SaveJobs(jobs)
folderSelect.Options = folderOptions(jobs)
@@ -373,7 +374,7 @@ func newMainView(w fyne.Window) (fyne.CanvasObject, func(time.Duration, bool)) {
dialog.ShowInformation("Scheduler paused", "Global pause is active. Resume the scheduler before running jobs.", w)
return
}
if !scheduler.RunNow(selected) {
if !sched.RunNow(selected) {
return
}
list.Refresh()
@@ -391,8 +392,8 @@ func newMainView(w fyne.Window) (fyne.CanvasObject, func(time.Duration, bool)) {
jobs[index].NextRun = "Scheduler paused"
}
}
if scheduler != nil {
scheduler.SetPaused(true)
if sched != nil {
sched.SetPaused(true)
}
events = append(events, newEvent(0, "Scheduler", "Paused", "All job execution paused"))
} else {
@@ -406,8 +407,8 @@ func newMainView(w fyne.Window) (fyne.CanvasObject, func(time.Duration, bool)) {
jobs[index].NextRun = "Waiting for scheduler"
}
}
if scheduler != nil {
scheduler.SetPaused(false)
if sched != nil {
sched.SetPaused(false)
}
events = append(events, newEvent(0, "Scheduler", "Resumed", "All job execution resumed"))
}
@@ -426,8 +427,8 @@ func newMainView(w fyne.Window) (fyne.CanvasObject, func(time.Duration, bool)) {
resumed := newEvent(current.ID, current.Name, "Resumed", "Job was enabled")
current.Logs = append([]event{resumed}, current.Logs...)
events = append(events, resumed)
if scheduler != nil {
scheduler.RefreshSchedule(selected)
if sched != nil {
sched.RefreshSchedule(selected)
}
} else {
current.LastState = "Paused"
@@ -435,8 +436,8 @@ func newMainView(w fyne.Window) (fyne.CanvasObject, func(time.Duration, bool)) {
paused := newEvent(current.ID, current.Name, "Paused", "Job was disabled")
current.Logs = append([]event{paused}, current.Logs...)
events = append(events, paused)
if scheduler != nil {
scheduler.RefreshSchedule(selected)
if sched != nil {
sched.RefreshSchedule(selected)
}
}
_ = store.SaveJobs(jobs)
@@ -503,13 +504,13 @@ func newMainView(w fyne.Window) (fyne.CanvasObject, func(time.Duration, bool)) {
jobLogs,
)
scheduler = core.NewScheduler(store, &jobs, func(record domain.RunRecord) {
sched = scheduler.NewScheduler(store, &jobs, func(record domain.RunRecord) {
// Scheduled runs happen on the scheduler goroutine. The callback updates
// the shared in-memory event list so History reflects background activity.
events = append(events, record)
refresh()
})
scheduler.Start()
sched.Start()
fixedSidebar := container.New(minWidthLayout{width: minJobsSidebarWidth}, sidebar)
jobsView := container.NewBorder(nil, nil, fixedSidebar, nil, container.NewPadded(details))
@@ -1,4 +1,4 @@
package core
package scheduler
import (
"context"
@@ -7,6 +7,7 @@ import (
"sync"
"time"
"gitea.mixdep.ru/mix/gosentry/src/core"
"gitea.mixdep.ru/mix/gosentry/src/domain"
"gitea.mixdep.ru/mix/gosentry/src/runner"
"github.com/robfig/cron/v3"
@@ -19,7 +20,7 @@ var cronParser = cron.NewParser(cron.Minute | cron.Hour | cron.Dom | cron.Month
// this keeps the early architecture simple while storage and scheduling are
// still in one desktop process.
type Scheduler struct {
store *Store
store *core.Store
jobs *[]domain.Job
onChange func(domain.RunRecord)
@@ -29,7 +30,7 @@ type Scheduler struct {
paused bool
}
func NewScheduler(store *Store, jobs *[]domain.Job, onChange func(domain.RunRecord)) *Scheduler {
func NewScheduler(store *core.Store, jobs *[]domain.Job, onChange func(domain.RunRecord)) *Scheduler {
ctx, cancel := context.WithCancel(context.Background())
s := &Scheduler{
store: store,
@@ -1,4 +1,4 @@
package core
package scheduler
import (
"strings"