Documentation ¶
Overview ¶
Package oversight makes a complete implementation of the Erlang supervision trees.
Refer to: https://erlang.org/doc/design_principles/sup_princ.html
supervisor := oversight.New( oversight.WithRestartStrategy(oversight.OneForOne()), oversight.Processes(func(ctx context.Context) error { select { case <-ctx.Done(): return nil case <-time.After(time.Second): log.Println(1) } return nil }), ) ctx, cancel := context.WithCancel(context.Background()) defer cancel() if err := supervisor.Start(ctx); err != nil { log.Fatal(err) }
Simple interface ¶
If you do not need to use nested trees, you might prefer using cirello.io/oversight/easy instead. It provides a OneForAll tree with the automatic halting disabled.
package main import oversight "cirello.io/oversight/easy" func main() { ctx, cancel := context.WithCancel(context.Background()) defer cancel() // use cancel() to halt the tree. ctx = oversight.WithContext(ctx) oversight.Add(ctx, func(ctx context.Context) { // ... }) }
This package is covered by this SLA: https://cirello.io/sla
Index ¶
- Constants
- Variables
- func ChildProcessName(ctx context.Context) string
- type ChildProcess
- type ChildProcessSpecification
- type ChildProcessState
- type Logger
- type Restart
- type Shutdown
- type State
- type Strategy
- type Tree
- func (t *Tree) Add(spec interface{}) error
- func (t *Tree) Children() []State
- func (t *Tree) Delete(name string) error
- func (t *Tree) GetErr() error
- func (t *Tree) GracefulShutdown(ctx context.Context) error
- func (t *Tree) Start(rootCtx context.Context) error
- func (t *Tree) Terminate(name string) error
- type TreeOption
- func DefaultMaximumRestartIntensity() TreeOption
- func DefaultRestartIntensity() TreeOption
- func DefaultRestartStrategy() TreeOption
- func NeverHalt() TreeOption
- func Process(specs ...ChildProcessSpecification) TreeOption
- func Processes(processes ...ChildProcess) TreeOption
- func WithLogger(logger Logger) TreeOption
- func WithMaximumRestartIntensity(maxR int, maxT time.Duration) TreeOption
- func WithRestartIntensity(maxR int, maxT time.Duration) TreeOption
- func WithRestartStrategy(strategy Strategy) TreeOption
- func WithSpecification(maxR int, maxT time.Duration, strategy Strategy) TreeOption
- func WithTree(subTree *Tree) TreeOption
Examples ¶
Constants ¶
Default restart intensity expectations.
DefaultChildProcessTimeout defines how long child worker process should wait before detachment.
Variables ¶
ErrInvalidChildProcessType is returned when caller tries to add an invalid child process to the oversight tree. The child process type must always be ChildProcessSpecification, ChildProcess, and *Tree.
ErrInvalidConfiguration is returned when tree has invalid settings.
ErrMissingContext is returned when a nil value is passed as context
ErrNoChildProcessLeft means that all processes in the supervisor are done, and there is no one left to restart.
ErrProcessNotRunning is returned when caller tries to terminated processes that are not running.
ErrTooManyFailures means that the supervisor detected that one of the child processes has failed too much and that it decided to fully stop.
ErrTreeNotRunning is returned to Add, Terminate and Delete calls when the oversight tree is initialized but not started yet; or when at that point in time is not running anymore.
ErrUnknownProcess is returned when runtime operations (like delete or terminate) failed because the process is not present.
Functions ¶
Types ¶
type ChildProcess ¶
ChildProcess is a function that can be supervised for restart.
type ChildProcessSpecification ¶
type ChildProcessSpecification struct { // Name is the human-friendly reference used for inspecting and // terminating child processes. If the same named is used twice, the // oversight tree will append a suffix to make it unique. Name string // Restart must be one of the Restart policies. The each oversight tree // implementation is free to interpret the result of this call. Restart Restart // Start initiates the child process in a panic-trapping cage. It does // not circumvent Go's panic-recover semantics. Avoid starting // goroutines inside the ChildProcess if they risk panic()'ing. Start ChildProcess // Shutdown defines the child process timeout. If the process is not // stopped within the specified duration, the oversight tree detached // the process and moves on. Null values mean wait forever. Shutdown Shutdown }
ChildProcessSpecification provides the complete interface to configure how the child process should behave itself in case of failures.
type ChildProcessState ¶
type ChildProcessState string
ChildProcessState represents the current lifecycle step of the child process.
const ( Starting ChildProcessState = "" Running ChildProcessState = "running" Failed ChildProcessState = "failed" Done ChildProcessState = "done" )
Child processes navigate through a sequence of states, that are atomically managed by the oversight tree to decide if child process needs to be started or not.
┌─────────────────────┐ │ │ │ ┌────────────┐ ▼ ┌───▶│ Failed │ ┌────────────┐ ┌────────────┐ │ └────────────┘ │ Starting │───▶│ Running │───┤ └────────────┘ └────────────┘ │ ┌────────────┐ └───▶│ Done │ └────────────┘
type Logger ¶
type Logger interface { Printf(format string, args ...interface{}) Println(args ...interface{}) }
Logger defines the interface for any logging facility to be compatible with oversight trees.
type Restart ¶
Restart is a function that decides if a worker has to be restarted or not according to its returned error.
type Shutdown ¶
type Shutdown func() (context.Context, context.CancelFunc)
Shutdown defines how the oversight handles child processes hanging after they are signaled to stop.
type State ¶
type State struct { Name string State ChildProcessState Stop func() }
State is a snapshot of the child process current state.
type Strategy ¶
type Strategy func(t *Tree, childProcess *childProcess)
Strategy defines how the supervisor handles individual failures and tree shutdowns (best effort). The shutdown is initiated in the reverse order of the start of the child processes. The Go scheduler implementation makes it impossible to guarantee any order regarding shutdown completion.
func OneForAll ¶
func OneForAll() Strategy
OneForAll ensures that if a child process terminates, all other child processes are terminated, and then all child processes, including the terminated one, are restarted.
func OneForOne ¶
func OneForOne() Strategy
OneForOne ensures that if a child process terminates, only that process is restarted.
func RestForOne ¶
func RestForOne() Strategy
RestForOne ensures that if a child process terminates, the rest of the child processes (that is, the child processes after the terminated process in start order) are terminated. Then the terminated child process and the rest of the child processes are restarted.
type Tree ¶
type Tree struct {
// contains filtered or unexported fields
}
Tree is the supervisor tree proper.
Example (SinglePermanent) ¶
ExampleTree_singlePermanent shows how to create a static tree of permanent child processes.
package main import ( "context" "fmt" "time" "cirello.io/oversight" ) func main() { supervise := oversight.New( oversight.Processes(func(ctx context.Context) error { select { case <-ctx.Done(): return nil case <-time.After(time.Second): fmt.Println(1) } return nil }), ) ctx, cancel := context.WithCancel(context.Background()) defer cancel() err := supervise.Start(ctx) if err != nil { fmt.Println(err) } }
Output: 1 1 too many failures
func New ¶
func New(opts ...TreeOption) *Tree
New creates a new oversight (supervisor) tree with the applied options.
func (*Tree) Add ¶
Add attaches a new child process to a running oversight tree. This call must be used on running oversight trees. If the tree is halted, it is going to fail with ErrTreeNotRunning. The valid types are ChildProcessSpecification, ChildProcess, func(context.Context) and *Tree. If the added child process is invalid, it is going to fail with ErrInvalidChildProcessType.
func (*Tree) Children ¶
Children returns the current set of child processes.
func (*Tree) Delete ¶
Delete stops the service in the oversight tree and remove from it. If the oversight tree runs out of processes to supervise, it will terminate itself with ErrNoChildProcessLeft. This call must be used on running oversight trees, if the tree is not started yet, it is going to block. If the tree is halted, it is going to fail with ErrTreeNotRunning.
func (*Tree) GracefulShutdown ¶ added in v1.1.0
GracefulShutdown stops the tree in reverse order. If the tree is not started, it returns ErrTreeNotRunning. If the given context is canceled, the shutdown is aborted.
func (*Tree) Start ¶
Start ignites the supervisor tree.
func (*Tree) Terminate ¶
Terminate stop the named process. Terminated child processes do not count as failures in the oversight tree restart policy. If the oversight tree runs out of processes to supervise, it will terminate itself with ErrNoChildProcessLeft. This call must be used on running oversight trees, if the tree is not started yet, it is going to block. If the tree is halted, it is going to fail with ErrTreeNotRunning.
type TreeOption ¶
type TreeOption func(*Tree)
TreeOption are applied to change the behavior of a Tree.
func DefaultMaximumRestartIntensity ¶ added in v1.0.4
func DefaultMaximumRestartIntensity() TreeOption
DefaultMaximumRestartIntensity redefines the tolerance for failures in the supervisor tree. It defaults to 1 restart (maxR) in the preceding 5 seconds (maxT).
Refer to https://erlang.org/doc/design_principles/sup_princ.html#tuning-the-intensity-and-period
func DefaultRestartIntensity ¶
func DefaultRestartIntensity() TreeOption
DefaultRestartIntensity is an alias for DefaultMaximumRestartIntensity.
Deprecated in favor of DefaultMaximumRestartIntensity.
func DefaultRestartStrategy ¶
func DefaultRestartStrategy() TreeOption
DefaultRestartStrategy redefines the supervisor behavior to use OneForOne.
func NeverHalt ¶
func NeverHalt() TreeOption
NeverHalt will configure the oversight tree to never stop in face of failure.
func Process ¶
func Process(specs ...ChildProcessSpecification) TreeOption
Process plugs one or more child processes to the supervisor tree. Process never reset the child process list.
func Processes ¶
func Processes(processes ...ChildProcess) TreeOption
Processes plugs one or more Permanent child processes to the supervisor tree. Processes never reset the child process list.
func WithLogger ¶
func WithLogger(logger Logger) TreeOption
WithLogger plugs a custom logger to the oversight tree.
func WithMaximumRestartIntensity ¶ added in v1.0.3
func WithMaximumRestartIntensity(maxR int, maxT time.Duration) TreeOption
WithMaximumRestartIntensity defines a custom tolerance for failures in the supervisor tree.
Refer to https://erlang.org/doc/design_principles/sup_princ.html#maximum-restart-intensity
func WithRestartIntensity ¶
func WithRestartIntensity(maxR int, maxT time.Duration) TreeOption
WithRestartIntensity is an alias for WithMaximumRestartIntensity. Deprecated in favor of WithMaximumRestartIntensity.
func WithRestartStrategy ¶
func WithRestartStrategy(strategy Strategy) TreeOption
WithRestartStrategy defines a custom restart strategy for the supervisor tree.
func WithSpecification ¶
func WithSpecification(maxR int, maxT time.Duration, strategy Strategy) TreeOption
WithSpecification defines a custom setup to tweak restart tolerance and strategy for the instance of oversight.
func WithTree ¶
func WithTree(subTree *Tree) TreeOption
WithTree is a shortcut to add a tree as a child process.