relax

package module
v0.0.0 Latest Latest
Warning

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

Go to latest
Published: Apr 2, 2024 License: MIT Imports: 7 Imported by: 0

README

Relax

...there's no need to panic.

Coverage

Go programs should panic, recover, and relax. Why?

In some situations, encountering an unrecoverable panic can be problematic. For example:

  • If your REST server crashes while handling a POST request, you may end up with a dangling resource in your database;
  • Applications that write state to filesystems may produce irrecoverable state if a series of dependant file writes is interrupted by a crash; and
  • When running tests, such as integration tests using Go's coverage capabilities, a panic can cause you to lose your prized test results.

Instead of crashing, relaxed Go programs always shutdown gracefully, even in the case of SIGINT, SIGTERM, and concurrent panics.

Relaxed Go programs will only shutdown after all running operations and connections have completed and closed, respectively.

This module is intended to aid in the development of relaxed Go programs. The main challenge in achieving this is to ensure that all panicking goroutines are recovered and lead to the graceful shutdown of the program. Read about panic and recover here for more detail.

Usage

Import the pkg:

import (
	"github.com/sergerad/relax"
)

Instantiate the main context in the main goroutine.

func main() {
	mainCtx := relax.Context()

This ensures that SIGINT/SIGTERM will cause all contexts used in the application to be Done().

If you have multiple, long running processes to run in your program, you can use RoutineGroup to launch them.

	group, ctx := relax.NewGroup(mainCtx)

You can use the RoutineGroup to launch goroutines which will return an error if they encounter a panic.

	group.Go(func() error {
		panic("failed")
	})

Finally, in the main goroutine, make sure to wait for the error group:

	if err := group.Wait(); err != nil {
		// Handle the error...
	}

When you only have a single goroutine to run, you can use Routine instead of RoutineGroup:

	routine := relax.Go(func() error {
		panic("failed")
	})
	if err := routine.Wait(); err != nil {
		// Handle the error...
	}

If you don't wish to wait for the result, you can register a callback:

	routine.Release(func(err error) {
		// Handle the error
	})

For more detailed usage, see examples and the *_test.go files.

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	// PanicError is returned when a panic is recovered
	// during the execution of a goroutine
	PanicError = fmt.Errorf("recovered from panic")
)

Functions

func Context

func Context() context.Context

Context instantiates a context that is cancelled only when the SIGINT/SIGTERM signals are received. This context should be set up in main() of your application.

Types

type Routine

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

Routine is a handle to a goroutine's error response. Panics that occur in this routine are converted into errors.

func Go

func Go(f func() error) *Routine

Go launches a goroutine that will return an error if the provided func panics or an error is returned by the provided func.

func (*Routine) Release

func (r *Routine) Release(handler func(error))

Release will call the handler against an error returned by this routine. Once a routine is released, waiting on it will return nil.

func (*Routine) Wait

func (r *Routine) Wait() error

Wait blocks until the goroutine corresponding to the Routine instance returns an error. Once an error is returned, all subsequent calls to Wait will return nil.

type RoutineGroup

type RoutineGroup struct {
	*errgroup.Group
}

RoutineGroup is a wrapper around golang.org/x/sync/errgroup.Group that recovers from panics and returns them as errors

func NewGroup

func NewGroup(ctx context.Context) (*RoutineGroup, context.Context)

NewGroup instantiates an RoutineGroup and corresponding context. This function should be used the same way as errgroup.WithContext() from golang.org/x/sync/errgroup

func (*RoutineGroup) Go

func (rg *RoutineGroup) Go(f func() error)

Go runs a provided func in a goroutine while ensuring that any panic is recovered and returned as an error

Directories

Path Synopsis
examples

Jump to

Keyboard shortcuts

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