V2bX/common/task/task.go

79 lines
1.2 KiB
Go
Raw Normal View History

2023-06-15 22:04:39 -04:00
package task
import (
"sync"
"time"
)
// Task is a task that runs periodically.
type Task struct {
// Interval of the task being run
Interval time.Duration
// Execute is the task function
Execute func() error
access sync.Mutex
timer *time.Timer
running bool
}
func (t *Task) hasClosed() bool {
t.access.Lock()
defer t.access.Unlock()
return !t.running
}
2023-06-17 15:37:27 -04:00
func (t *Task) checkedExecute(first bool) error {
2023-06-15 22:04:39 -04:00
if t.hasClosed() {
return nil
}
t.access.Lock()
defer t.access.Unlock()
2023-06-17 15:37:27 -04:00
if first {
if err := t.Execute(); err != nil {
t.running = false
return err
}
}
2023-06-15 22:04:39 -04:00
if !t.running {
return nil
}
t.timer = time.AfterFunc(t.Interval, func() {
2023-06-17 15:37:27 -04:00
t.checkedExecute(true)
2023-06-15 22:04:39 -04:00
})
return nil
}
// Start implements common.Runnable.
func (t *Task) Start(first bool) error {
t.access.Lock()
if t.running {
t.access.Unlock()
return nil
}
t.running = true
t.access.Unlock()
2023-06-17 15:37:27 -04:00
if err := t.checkedExecute(first); err != nil {
2023-06-15 22:04:39 -04:00
t.access.Lock()
t.running = false
t.access.Unlock()
return err
}
return nil
}
// Close implements common.Closable.
func (t *Task) Close() {
t.access.Lock()
defer t.access.Unlock()
t.running = false
if t.timer != nil {
t.timer.Stop()
t.timer = nil
}
}