blob: 3d7d29abf2d8a876d2a7ea65dc2d9fefe5f781df [file] [log] [blame]
package background_task
import (
"time"
)
// A helper to run a function in the background at a specified interval.
// Can be used for a lot of different things.
type backgroundTask struct {
ticker *time.Ticker
stopRequested chan bool
done chan bool
}
func New(interval time.Duration) backgroundTask {
return backgroundTask{
ticker: time.NewTicker(interval),
stopRequested: make(chan bool, 1),
done: make(chan bool, 1),
}
}
func (task *backgroundTask) Start(taskFunc func()) {
go func() {
// Signal the Stop() function below when the goroutine has
// finished executing.
defer func() { task.done <- true }()
// time.Ticker doesn't perform an immediate invocation.
// Instead, it waits for the specified duration before
// triggering the first tick. We pretend that there's a tick
// here by invoking the callback manually.
taskFunc()
for {
select {
case <-task.stopRequested:
return
case <-task.ticker.C:
taskFunc()
}
}
}()
}
// Stops the background task from within the background task. The Stop()
// function still needs to be called from outside the task.
func (task *backgroundTask) StopFromWithinTask() {
task.stopRequested <- true
}
func (task *backgroundTask) Stop() {
task.stopRequested <- true
task.ticker.Stop()
<-task.done
close(task.stopRequested)
close(task.done)
}