88 lines
2.1 KiB
Go
88 lines
2.1 KiB
Go
package scheduler
|
|
|
|
import (
|
|
"fmt"
|
|
"log"
|
|
"time"
|
|
|
|
"git.nyne.dev/x/backup/backup"
|
|
"git.nyne.dev/x/backup/config"
|
|
)
|
|
|
|
// Scheduler handles the backup scheduling
|
|
type Scheduler struct {
|
|
config *config.Config
|
|
backupManager *backup.BackupManager
|
|
ticker *time.Ticker
|
|
quit chan struct{}
|
|
}
|
|
|
|
// NewScheduler creates a new scheduler
|
|
func NewScheduler(cfg *config.Config) (*Scheduler, error) {
|
|
bm, err := backup.NewBackupManager(cfg)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to create backup manager: %w", err)
|
|
}
|
|
|
|
return &Scheduler{
|
|
config: cfg,
|
|
backupManager: bm,
|
|
quit: make(chan struct{}),
|
|
}, nil
|
|
}
|
|
|
|
// Start starts the scheduler
|
|
func (s *Scheduler) Start() error {
|
|
interval, err := s.config.Options.ParseInterval()
|
|
if err != nil {
|
|
return fmt.Errorf("failed to parse interval: %w", err)
|
|
}
|
|
|
|
log.Printf("Starting scheduler with interval: %s\n", interval)
|
|
|
|
// Only run an immediate backup if no recent backup exists within the configured interval.
|
|
// This prevents redundant backups when the container restarts frequently.
|
|
lastBackupTime, err := s.backupManager.GetLastBackupTime()
|
|
if err != nil {
|
|
log.Printf("Warning: could not determine last backup time, will run backup now: %v\n", err)
|
|
}
|
|
|
|
elapsed := time.Since(lastBackupTime)
|
|
if lastBackupTime.IsZero() || elapsed >= interval {
|
|
log.Println("Running initial backup...")
|
|
if err := s.backupManager.RunBackup(); err != nil {
|
|
log.Printf("Initial backup failed: %v\n", err)
|
|
}
|
|
} else {
|
|
remaining := interval - elapsed
|
|
log.Printf("Skipping initial backup: last backup was %s ago (interval: %s), next backup in %s\n",
|
|
elapsed.Round(time.Second), interval, remaining.Round(time.Second))
|
|
}
|
|
|
|
s.ticker = time.NewTicker(interval)
|
|
|
|
go func() {
|
|
for {
|
|
select {
|
|
case <-s.ticker.C:
|
|
log.Println("Starting scheduled backup...")
|
|
if err := s.backupManager.RunBackup(); err != nil {
|
|
log.Printf("Backup failed: %v\n", err)
|
|
}
|
|
case <-s.quit:
|
|
s.ticker.Stop()
|
|
return
|
|
}
|
|
}
|
|
}()
|
|
|
|
log.Println("Scheduler started successfully")
|
|
|
|
return nil
|
|
}
|
|
|
|
// Stop stops the scheduler
|
|
func (s *Scheduler) Stop() {
|
|
close(s.quit)
|
|
}
|