aboutsummaryrefslogtreecommitdiff
path: root/internal/service/service.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/service/service.go')
-rw-r--r--internal/service/service.go98
1 files changed, 67 insertions, 31 deletions
diff --git a/internal/service/service.go b/internal/service/service.go
index 577a4b4..12f79dc 100644
--- a/internal/service/service.go
+++ b/internal/service/service.go
@@ -81,10 +81,9 @@ func (s *Service) AddMirror(arg *Mirror) error {
}
}
- record := &mirrorRecord{
- Mirror: arg,
- NextRun: time.Now().Add(RandomDuration(*s.cfg.MinInterval, *s.cfg.MaxInterval).Duration),
- }
+ record := &mirrorRecord{Mirror: arg}
+ scheduleNextRun(s.cfg, record)
+
s.mirrors = append(s.mirrors, record)
return nil
@@ -96,7 +95,7 @@ func (s *Service) scheduled(yield func(*mirrorRecord) bool) {
now := time.Now()
for _, m := range s.mirrors {
- if m.NextRun.After(now) {
+ if m.NextRun.IsZero() || m.NextRun.After(now) {
continue
}
@@ -230,6 +229,37 @@ func (s *Service) RemoveMirror(arg *Mirror) error {
return nil
}
+func scheduleNextRun(cfg *Config, m *mirrorRecord) {
+ if !m.NextRun.IsZero() {
+ return
+ }
+
+ // Default to it not existing, leaving error handling for others.
+ toPathExists := false
+ _, err := os.Stat(m.To.Path)
+ if err == nil {
+ toPathExists = true
+ }
+
+ minInterval := *cfg.MinInterval
+ if m.MinInterval != nil {
+ minInterval = *m.MinInterval
+ }
+ maxInterval := *cfg.MaxInterval
+ if m.MaxInterval != nil {
+ maxInterval = *m.MaxInterval
+ }
+
+ if minInterval.Duration > 0 || maxInterval.Duration > 0 || !toPathExists {
+ lastRun := m.LastRun
+ if lastRun.IsZero() {
+ lastRun = time.Now()
+ }
+
+ m.NextRun = lastRun.Add(RandomDuration(minInterval, maxInterval).Duration)
+ }
+}
+
// Reload reloads the service with the given configuration.
func (s *Service) Reload(arg *Config) {
s.mirrorsLock.Lock()
@@ -250,43 +280,47 @@ func (s *Service) Reload(arg *Config) {
mirrors := make([]*mirrorRecord, 0)
for _, m := range cfg.Mirrors {
+ record := &mirrorRecord{Mirror: m}
+
oldM, ok := mirrorsByDest[m.To.String()]
- if !ok {
- mirrors = append(
- mirrors,
- &mirrorRecord{
- Mirror: m,
- LastRun: time.Time{},
- NextRun: time.Now().Add(RandomDuration(*s.cfg.MinInterval, *s.cfg.MaxInterval).Duration),
- },
- )
+ if ok {
+ delete(mirrorsByDest, m.To.String())
- continue
- }
+ record.LastRun = oldM.LastRun
+ record.NextRun = oldM.NextRun
- delete(mirrorsByDest, m.To.String())
+ // The run times may be out of sync with the new
+ // configuration.
+ lastRun := oldM.LastRun
+ if lastRun.IsZero() {
+ lastRun = time.Now()
+ }
- lastRun := oldM.LastRun
- if lastRun.IsZero() {
- lastRun = time.Now()
- }
+ minInterval := *cfg.MinInterval
+ if m.MinInterval != nil {
+ minInterval = *m.MinInterval
+ }
+ maxInterval := *cfg.MaxInterval
+ if m.MaxInterval != nil {
+ maxInterval = *m.MaxInterval
+ }
- untilNextRun := Duration{oldM.NextRun.Sub(lastRun)}
- untilNextRun = cfg.MinInterval.Max(&untilNextRun)
- untilNextRun = cfg.MaxInterval.Min(&untilNextRun)
+ waitTime := oldM.NextRun.Sub(lastRun)
+ if waitTime < minInterval.Duration || waitTime > maxInterval.Duration {
+ record.NextRun = time.Time{}
+ }
- // Records match up.
- record := mirrorRecord{
- Mirror: m,
- LastRun: oldM.LastRun,
- NextRun: time.Now().Add(untilNextRun.Duration),
}
+
+ scheduleNextRun(s.cfg, record)
+
mirrors = append(
mirrors,
- &record,
+ record,
)
}
+ // Swap out the old with the new.
s.mirrors = mirrors
}
@@ -315,7 +349,9 @@ mainLoop:
}
m.LastRun = time.Now()
- m.NextRun = time.Now().Add(RandomDuration(*s.cfg.MinInterval, *s.cfg.MaxInterval).Duration)
+ m.NextRun = time.Time{}
+
+ scheduleNextRun(s.cfg, m)
return true
})