Files

98 lines
1.7 KiB
Go
Raw Permalink Normal View History

2026-05-22 20:26:11 -04:00
package triggers
import (
"sync"
"time"
"github.com/Silo-Server/silo-server/internal/taskmanager"
)
const startupDelay = 5 * time.Second
// StartupTrigger fires once, shortly after Start() is called. Subsequent
// calls to Start() (e.g. re-arming after execution) are no-ops.
type StartupTrigger struct {
cfg taskmanager.TriggerConfig
ch chan struct{}
delay time.Duration
2026-05-22 20:26:11 -04:00
nextRun time.Time
timer *time.Timer
stopCh chan struct{}
fired bool
mu sync.Mutex
}
func NewStartupTrigger(cfg taskmanager.TriggerConfig) *StartupTrigger {
return &StartupTrigger{
cfg: cfg,
ch: make(chan struct{}, 1),
delay: startupDelay,
2026-05-22 20:26:11 -04:00
}
}
func (s *StartupTrigger) Start(_ *taskmanager.ExecutionResult) {
s.mu.Lock()
defer s.mu.Unlock()
// Drain any stale signal from a previous timer fire.
select {
case <-s.ch:
default:
}
if s.fired {
s.nextRun = time.Time{}
2026-05-22 20:26:11 -04:00
return
}
s.fired = true
stopCh := make(chan struct{})
s.nextRun = time.Now().Add(s.delay)
timer := time.NewTimer(s.delay)
s.stopCh = stopCh
s.timer = timer
2026-05-22 20:26:11 -04:00
go func() {
select {
case <-stopCh:
if !timer.Stop() {
2026-05-22 20:26:11 -04:00
select {
case <-timer.C:
2026-05-22 20:26:11 -04:00
default:
}
}
return
case <-timer.C:
s.mu.Lock()
s.nextRun = time.Time{}
s.mu.Unlock()
2026-05-22 20:26:11 -04:00
select {
case s.ch <- struct{}{}:
default:
}
}
}()
}
func (s *StartupTrigger) Stop() {
s.mu.Lock()
defer s.mu.Unlock()
if s.stopCh != nil {
select {
case <-s.stopCh:
default:
close(s.stopCh)
}
}
s.nextRun = time.Time{}
2026-05-22 20:26:11 -04:00
}
func (s *StartupTrigger) NextRunTime() time.Time {
s.mu.Lock()
defer s.mu.Unlock()
return s.nextRun
}
func (s *StartupTrigger) Config() taskmanager.TriggerConfig { return s.cfg }
func (s *StartupTrigger) C() <-chan struct{} { return s.ch }