Skip to content
Package tasks is an easy to use in-process scheduler for recurring tasks in Go
Go
Branch: master
Clone or download
madflojo Merge pull request #2 from madflojo/AfterFunc
Moving to AfterFunc which should be more efficient
Latest commit 3451a04 Jan 1, 2020
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
.github
vendor
.gitignore
.travis.yml First working commit with most of a scheduler Dec 24, 2019
CONTRIBUTING.md
LICENSE
README.md
go.mod
go.sum First working commit with most of a scheduler Dec 24, 2019
tasks.go Moving to AfterFunc which should be more efficient Jan 1, 2020
tasks_test.go

README.md

Tasks

Build Status Coverage Status Go Report Card Documentation

Package tasks is an easy to use in-process scheduler for recurring tasks in Go. Tasks is focused on high frequency tasks that run quick, and often. The goal of Tasks is to support concurrent running tasks at scale without scheduler induced jitter.

Tasks is focused on accuracy of task execution. To do this each task is called within it's own goroutine. This ensures that long execution of a single invocation does not throw the schedule as a whole off track.

As usage of this scheduler scales, it is expected to have a larger number of sleeping goroutines. As it is designed to leverage Go's ability to optimize goroutine CPU scheduling.

For simplicity this task scheduler uses the time.Duration type to specify intervals. This allows for a simple interface and flexible control over when tasks are executed.

Below is an example of starting the scheduler and registering a new task that runs every 30 seconds.

// Start the Scheduler
scheduler := tasks.New()
defer scheduler.Stop()

// Add a task
id, err := scheduler.Add(&tasks.Task{
  Interval: time.Duration(30 * time.Second),
  TaskFunc: func() error {
    // Put your logic here
  }(),
})
if err != nil {
  // Do Stuff
}

Sometimes schedules need to started at a later time. This package provides the ability to start a task only after a certain time. The below example shows this in practice.

// Add a recurring task for every 30 days, starting 30 days from now
id, err := scheduler.Add(&tasks.Task{
  Interval: time.Duration(30 * (24 * time.Hour)),
  StartAfter: time.Now().Add(30 * (24 * time.Hour)),
  TaskFunc: func() error {
    // Put your logic here
  }(),
})
if err != nil {
  // Do Stuff
}

It is also common for applications to run a task only once. The below example shows scheduling a task to run only once after waiting for 60 seconds.

// Add a one time only task for 60 seconds from now
id, err := scheduler.Add(&tasks.Task{
  Interval: time.Duration(60 * time.Second)
  RunOnce:  true,
  TaskFunc: func() error {
    // Put your logic here
  }(),
})
if err != nil {
  // Do Stuff
}

One powerful feature of Tasks is that it allows users to specify custom error handling. This is done by allowing users to define a function that is called when a task returns an error. The below example shows scheduling a task that logs when an error occurs.

// Add a task with custom error handling
id, err := scheduler.Add(&tasks.Task{
  Interval: time.Duration(30 * time.Second),
  TaskFunc: func() error {
    // Put your logic here
  }(),
  ErrFunc: func(e error) {
    log.Printf("An error occured when executing task %s - %s", id, e)
  }(),
})
if err != nil {
  // Do Stuff
}
You can’t perform that action at this time.