GraphQL API and utilities for the rpdata project
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
|
|
package task
import ( "context" "sync" "time" )
var globalCtx, globalCancel = context.WithCancel(context.Background())
// A Task is a wrapper around a function that offers scheduling
// and syncronization.
type Task struct { mutex sync.Mutex ctx context.Context ctxCancel context.CancelFunc waitDuration time.Duration scheduled bool callback func() error }
// Context gets the task's context.
func (task *Task) Context() context.Context { return task.ctx }
// Stop stops a task. This should not be done to stop a single run,
// but as a way to cancel it forever.
func (task *Task) Stop() { task.ctxCancel() }
// Schedule schedules a task for later execution.
func (task *Task) Schedule() { // Don't if the context is closed.
select { case <-task.Context().Done(): return default: }
task.mutex.Lock() if task.scheduled { task.mutex.Unlock() return } task.scheduled = true task.mutex.Unlock()
go func() { <-time.After(task.waitDuration)
// Mark as no longer scheduled
task.mutex.Lock() task.scheduled = false task.mutex.Unlock()
// Don't if the task is cancelled
select { case <-task.Context().Done(): return default: }
task.callback() }() }
// New makes a new task with the callback.
func New(waitDuration time.Duration, callback func() error) *Task { ctx, ctxCancel := context.WithCancel(globalCtx)
return &Task{ callback: callback, ctx: ctx, ctxCancel: ctxCancel, waitDuration: waitDuration, } }
// StopAll stops all tasks.
func StopAll() { globalCancel() }
|