background

package module
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Apr 29, 2024 License: BSD-3-Clause Imports: 9 Imported by: 0

README

go.strv.io/background

Continuous Integration codecov

Never lose your goroutine again.
Built with ❤️ at STRV

About

This package provides mechanism to easily run a task (a function) in a goroutine and provides mechanisms to wait for all tasks to finish (a synchronisation point). Addiionally, you can attach an observer to the background manager and get notified when something interesting happens to your task - like when it finishes, errors or takes too long to complete. This allows you to centralise your error reporting and logging.

The purpose of the central synchronisation point for all your background goroutines is to make sure that your application does not exit before all goroutines have finished. You can trigger the synchronisation when your application receives a terminating signal, for example, and wait for all tasks to finish before allowing the application to exit.

Installation

go get go.strv.io/background

Usage

There are two types of tasks you can execute:

  • one-off: a task that runs once and then finishes
  • looping: a task that runs repeatedly until it is stopped

One-off tasks are great for triggering a single operation in the background, like sending an email or processing a file. Looping tasks are great for running a background worker that processes a queue of items, like reading from an AWS SQS queue periodically.

Additionally, each task can define its retry policies, which allows you to automatically retry the task if it fails. For one-off tasks, the task is repeated until its retry policy says it should stop, then the task is considered finished. For looping tasks, the retry policy is applied to each iteration of the task - upon failure, the task is retried using its defined retry policy and when the policy says it should stop, the task continues on to the next iteration and the process repeats.

Initialising the manager

package main

import (
  "context"

  "go.strv.io/background"
  "go.strv.io/background/observer"
)

func main() {
  manager := background.NewManagerWithOptions(background.Options{
    // Use one of the provided observers that prints logs to the console using log/slog
    // Feel free to implement your own.
    Observer: observer.Slog{},
  })

  // Share the manager with the rest of your application

  interrupt := make(chan os.Signal, 1)
	signal.Notify(interrupt, os.Interrupt)
  <-interrupt
  // Wait for all tasks to finish, then allow the application to exit
  manager.Close()
}

Scheduling tasks

import (
  "time"

  "go.strv.io/background"
  "go.strv.io/background/task"
  "github.com/kamilsk/retry/v5/strategy"
)

maanger := background.NewManagerWithOptions(background.Options{
  Observer: observer.Slog{},
})

// Executes a one-off task - the task will run only once (except if it fails and has a retry policy)
oneoff := task.Task{
  Type: task.TypeOneOff,
  Fn: func(ctx context.Context) error {
    // Do something interesting...
    <-time.After(3 * time.Second)
    return nil
  },
  Retry: task.Retry{
    strategy.Limit(3),
  }
}

manager.RunTask(context.Background(), oneoff)

// Execute a looping task - the task will run repeatedly until it is stopped
looping := task.Task{
  Type: task.TypeLoop,
  Fn: func(ctx context.Context) error {
    // Do something interesting...
    <-time.After(3 * time.Second)
    return nil
  },
  Retry: task.Retry{
    strategy.Limit(3),
  }
}

// Execute the task to be continuously run in an infinite loop until manager.Close() is called
manager.RunTask(context.Background(), looping)

Examples

You can find a sample executable in the examples folder. To run them, clone the repository and run:

go run examples/slog/slog.go

License

See the LICENSE file for details.

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrUnknownType is returned when the task type is not a valid value of Type.
	ErrUnknownType = errors.New("unknown task type")
)

Functions

This section is empty.

Types

type Manager

type Manager struct {
	// contains filtered or unexported fields
}

Manager keeps track of running goroutines and provides mechanisms to wait for them to finish or cancel their execution. `Meta` is whatever you wish to associate with this task, usually something that will help you keep track of the tasks in the observer.

func NewManager

func NewManager() *Manager

NewManager creates a new instance of Manager with default options and no observer.

func NewManagerWithOptions

func NewManagerWithOptions(options Options) *Manager

NewManagerWithOptions creates a new instance of Manager with the provided options and observer.

func (*Manager) Cancel

func (m *Manager) Cancel()

Cancel blocks until all loop tasks finish their current loop and stops looping further. The tasks' context is not cancelled. Adding a new loop task after calling Cancel() will cause the task to be ignored and not run.

func (*Manager) Close

func (m *Manager) Close()

Close is a convenience method that calls Wait() and Cancel() in parallel. It blocks until all tasks have finished.

func (*Manager) CountOf

func (m *Manager) CountOf(t task.Type) int

CountOf returns the number of tasks of the specified type that are currently running. When the TaskType is invalid it returns 0.

func (*Manager) Run

func (m *Manager) Run(ctx context.Context, fn task.Fn)

Run executes the provided function once in a goroutine.

func (*Manager) RunTask

func (m *Manager) RunTask(ctx context.Context, definition task.Task)

RunTask executes the provided task in a goroutine. The task will be executed according to its type; by default, only once (TaskTypeOneOff).

func (*Manager) Wait

func (m *Manager) Wait()

Wait blocks until all running one-off tasks have finished. Adding more one-off tasks will prolong the wait time.

type Options

type Options struct {
	// StalledThreshold is the amount of time within which the task should return before it is considered stalled. Note
	// that no effort is made to actually stop or kill the task.
	StalledThreshold time.Duration
	// Observer allows you to register monitoring functions that are called when something happens with the tasks that you
	// execute. These are useful for logging, monitoring, etc.
	Observer observer.Observer
	// Retry defines the default retry strategies that will be used for all tasks unless overridden by the task. Several
	// strategies are provided by https://pkg.go.dev/github.com/kamilsk/retry/v5/strategy package.
	Retry task.Retry
}

Options provides a means for configuring the background manager and providing the observer to it.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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