background

package module
v1.0.0 Latest Latest
Warning

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

Go to latest
Published: Feb 19, 2024 License: MIT Imports: 2 Imported by: 0

README

github.com/robertrossmann/background

A package that keeps track of goroutines and allows you to wait for them to finish when it's time to shut down your application.

Purpose

In Go, when the main function returns, any pending goroutines are terminated. This means that we need to keep track of them somehow so that main can wait for them to finish before returning. This is also useful in the context of servers - when the server receives a terminating signal from the host OS (ie. due to a new release being deployed) the application needs a way to delay the shutdown long enough for the goroutines to finish before allowing itself to be terminated.

This library makes that management process easier to manage and adds some extra functionality on top, for good measure.

⚠️ By no means is this a replacement for proper job queue system! The intended use case is for small, relatiely fast functions that either do the actual work or schedule a job in some kind of a queue to do that work. Since even putting a job into a queue takes some time, you can remove that time from the client's request/response cycle and make your backend respond faster.

Installation

go get github.com/robertrossmann/background

Usage

package main

import (
  "context"

  "github.com/robertrossmann/background"
)

type BackgroundMetadata string

func main() {
  // Create a new background manager
  mgr := background.NewManager[BackgroundMetadata]()

  mgr.Run(context.Background(), "goroutine-1", func(ctx context.Context) error {
    // Do some work here
    return nil
  })

  // Attach some monitoring logic for logging or similar purpose
  mgr.OnTaskFailed = func(ctx context.Context, meta BackgroundMetadata, err error) {
    // Log the error, inspect the metadata, etc.
  }

  // Wait for all goroutines to finish
  // Make sure you stop your components from adding more tasks
  bg.Wait()
  // Now it's safe to terminate the process
}

License

See the LICENSE file for details.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Manager

type Manager[Meta any] struct {

	// OnTaskAdded is called immediately after calling Run(). You can use this for logging, metrics or other purposes.
	OnTaskAdded func(ctx context.Context, meta Meta)
	// OnTaskSucceeded is called immediately after Task returns. You can use this for logging, metrics or other purposes.
	OnTaskSucceeded func(ctx context.Context, meta Meta)
	// OnTaskFailed is called immediately after Task returns with an error. You can use this for logging, metrics or other
	// purposes.
	OnTaskFailed func(ctx context.Context, meta Meta, err error)
	// contains filtered or unexported fields
}

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

This is useful in context of HTTP servers, where a customer request may result in some kind of background processing activity that should not block the response and you schedule a goroutine to handle it. However, if your server receives a termination signal and you do not wait for these goroutines to finish, the goroutines will be killed before they can run to completion. This package is not a replacement for a proper task queue system but it is a great package to schedule the queue jobs without the customer waiting for that to happen while at the same time being able to wait for all those goroutines to finish before allowing the process to exit.

func NewManager

func NewManager[Meta any]() *Manager[Meta]

NewManager creates a new instance of Manager with the provided generic type for the metadata argument.

func (*Manager[Meta]) Len

func (m *Manager[Meta]) Len() int

Len returns the number of currently running tasks

func (*Manager[Meta]) Run

func (m *Manager[Meta]) Run(ctx context.Context, meta Meta, task Task)

Run schedules the provided task to be executed in a goroutine. `Meta` is whatever you wish to associate with the task.

func (*Manager[Meta]) Wait

func (m *Manager[Meta]) Wait()

Wait blocks until all scheduled tasks have finished.

type Task

type Task func(ctx context.Context) error

Task is the function to be executed in a goroutine

Jump to

Keyboard shortcuts

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