supervisor

package
v0.0.0-...-a8a8cbe Latest Latest
Warning

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

Go to latest
Published: Aug 25, 2021 License: Apache-2.0 Imports: 14 Imported by: 0

Documentation

Index

Examples

Constants

This section is empty.

Variables

View Source
var (
	// WithPropagatePanic prevents the Supervisor from catching panics in runnables and treating them as failures.
	// This is useful to enable for testing and local debugging.
	WithPropagatePanic = func(s *supervisor) {
		s.propagatePanic = true
	}
)

Functions

func Logger

func Logger(ctx context.Context) *zap.Logger

Logger returns a Zap logger that will be named after the Distinguished Name of a the runnable (ie its place in the supervision tree, dot-separated).

func New

func New(ctx context.Context, logger *zap.Logger, rootRunnable Runnable, opts ...SupervisorOpt) *supervisor

New creates a new supervisor with its root running the given root runnable. The given context can be used to cancel the entire supervision tree.

Example
// Minimal runnable that is immediately done.
childC := make(chan struct{})
child := func(ctx context.Context) error {
	Signal(ctx, SignalHealthy)
	close(childC)
	Signal(ctx, SignalDone)
	return nil
}

log, _ := zap.NewDevelopment()

// Start a supervision tree with a root runnable.
ctx, ctxC := context.WithCancel(context.Background())
defer ctxC()
New(ctx, log, func(ctx context.Context) error {
	err := Run(ctx, "child", child)
	if err != nil {
		return fmt.Errorf("could not run 'child': %w", err)
	}
	Signal(ctx, SignalHealthy)

	t := time.NewTicker(time.Second)
	defer t.Stop()

	// Do something in the background, and exit on context cancel.
	for {
		select {
		case <-t.C:
			fmt.Printf("tick!")
		case <-ctx.Done():
			return ctx.Err()
		}
	}
})

// root.child will close this channel.
<-childC
Output:

func Run

func Run(ctx context.Context, name string, runnable Runnable) error

Run starts a single runnable in its own group.

func RunGroup

func RunGroup(ctx context.Context, runnables map[string]Runnable) error

RunGroup starts a set of runnables as a group. These runnables will run together, and if any one of them quits unexpectedly, the result will be canceled and restarted. The context here must be an existing Runnable context, and the spawned runnables will run under the node that this context represents.

func Signal

func Signal(ctx context.Context, signal SignalType)

Signal tells the supervisor that the calling runnable has reached a certain state of its lifecycle. All runnables should SignalHealthy when they are ready with set up, running other child runnables and are now 'serving'.

Types

type Runnable

type Runnable func(ctx context.Context) error

A Runnable is a function that will be run in a goroutine, and supervised throughout its lifetime. It can in turn start more runnables as its children, and those will form part of a supervision tree. The context passed to a runnable is very important and needs to be handled properly. It will be live (non-errored) as long as the runnable should be running, and canceled (ctx.Err() will be non-nil) when the supervisor wants it to exit. This means this context is also perfectly usable for performing any blocking operations.

func Command

func Command(name string, arg ...string) Runnable

Command will create a Runnable that starts a long-running command, whose exit is determined to be a failure.

func GRPCServer

func GRPCServer(srv *grpc.Server, lis net.Listener, graceful bool) Runnable

GRPCServer creates a Runnable that serves gRPC requests as longs as it's not canceled. If graceful is set to true, the server will be gracefully stopped instead of plain stopped. This means all pending RPCs will finish, but also requires streaming gRPC handlers to check their context liveliness and exit accordingly. If the server code does not support this, `graceful` should be false and the server will be killed violently instead.

type SignalType

type SignalType int
const (
	// The runnable is healthy, done with setup, done with spawning more Runnables, and ready to serve in a loop.
	// The runnable needs to check the parent context and ensure that if that context is done, the runnable exits.
	SignalHealthy SignalType = iota
	// The runnable is done - it does not need to run any loop. This is useful for Runnables that only set up other
	// child runnables. This runnable will be restarted if a related failure happens somewhere in the supervision tree.
	SignalDone
)

type SupervisorOpt

type SupervisorOpt func(s *supervisor)

SupervisorOpt are runtime configurable options for the supervisor.

Jump to

Keyboard shortcuts

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