tasks

package module
v1.0.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 12, 2021 License: MIT Imports: 5 Imported by: 0

README

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 occurred when executing task %s - %s", id, e)
  }(),
})
if err != nil {
  // Do Stuff
}

Documentation

Overview

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 occurred when executing task %s - %s", id, e)
	}(),
})
if err != nil {
	// Do Stuff
}

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Scheduler

type Scheduler struct {
	sync.RWMutex
	// contains filtered or unexported fields
}

Scheduler stores the internal task list and provides an interface for task management.

func New

func New() *Scheduler

New will create a new scheduler instance that allows users to create and manage tasks.

func (*Scheduler) Add

func (schd *Scheduler) Add(t *Task) (string, error)

Add will add a task to the task list and schedule it. Once added, tasks will wait the defined time interval and then execute. This means a task with a 15 second interval will be triggered 15 seconds after Add is complete. Not before or after (excluding typical machine time jitter).

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

func (*Scheduler) Del

func (schd *Scheduler) Del(name string)

Del will unschedule the specified task and remove it from the task list. Deletion will prevent future invocations of a task, but not interrupt a trigged task.

func (*Scheduler) Lookup

func (schd *Scheduler) Lookup(name string) (*Task, error)

Lookup will find the specified task from the internal task list using the task ID provided.

The returned task should be treated as read-only, and not modified outside of this package. Doing so, may cause panics.

func (*Scheduler) Stop

func (schd *Scheduler) Stop()

Stop is used to unschedule and delete all tasks owned by the scheduler instance.

func (*Scheduler) Tasks

func (schd *Scheduler) Tasks() map[string]*Task

Tasks is used to return a copy of the internal tasks map.

The returned task should be treated as read-only, and not modified outside of this package. Doing so, may cause panics.

type Task

type Task struct {

	// Interval is the frequency that the task executes. Defining this at 30 seconds, will result in a task that
	// runs every 30 seconds.
	//
	// The below are common examples to get started with.
	//
	//  // Every 30 seconds
	//  time.Duration(30 * time.Second)
	//  // Every 5 minutes
	//  time.Duration(5 * time.Minute)
	//  // Every 12 hours
	//  time.Duration(12 * time.Hour)
	//  // Every 30 days
	//  time.Duration(30 * (24 * time.Hour))
	//
	Interval time.Duration

	// RunOnce is used to set this task as a single execution task. By default, tasks will continue executing at
	// the interval specified until deleted. With RunOnce enabled the first execution of the task will result in
	// the task self deleting.
	RunOnce bool

	// StartAfter is used to specify a start time for the scheduler. When set, tasks will wait for the specified
	// time to start the schedule timer.
	StartAfter time.Time

	// TaskFunc is the user defined function to execute as part of this task.
	TaskFunc func() error

	// ErrFunc allows users to define a function that is called when tasks return an error. If ErrFunc is nil,
	// errors from tasks will be ignored.
	ErrFunc func(error)

	sync.Mutex
	// contains filtered or unexported fields
}

Task contains the scheduled task details and control mechanisms. This struct is used during the creation of tasks. It allows users to control how and when tasks are executed.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL