89 lines
1.6 KiB
Go
89 lines
1.6 KiB
Go
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{}
|
|
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),
|
|
}
|
|
}
|
|
|
|
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 {
|
|
return
|
|
}
|
|
s.fired = true
|
|
|
|
s.stopCh = make(chan struct{})
|
|
s.nextRun = time.Now().Add(startupDelay)
|
|
s.timer = time.NewTimer(startupDelay)
|
|
|
|
go func() {
|
|
select {
|
|
case <-s.stopCh:
|
|
if !s.timer.Stop() {
|
|
select {
|
|
case <-s.timer.C:
|
|
default:
|
|
}
|
|
}
|
|
return
|
|
case <-s.timer.C:
|
|
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)
|
|
}
|
|
}
|
|
}
|
|
|
|
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 }
|