Documentation ¶
Overview ¶
Example ¶
package main import ( "context" "fmt" "io" "log" "net/http" "time" "github.com/joshuarubin/lifecycle" ) func main() { // This is only to ensure that the example completes const timeout = 10 * time.Millisecond ctx, cancel := context.WithTimeout(context.Background(), timeout) defer cancel() // At the top of your application ctx = lifecycle.New( ctx, lifecycle.WithTimeout(30*time.Second), // optional ) helloHandler := func(w http.ResponseWriter, req *http.Request) { _, _ = io.WriteString(w, "Hello, world!\n") } mux := http.NewServeMux() mux.HandleFunc("/hello", helloHandler) srv := &http.Server{ Addr: ":8080", Handler: mux, } var start, finish time.Time lifecycle.GoErr(ctx, func() error { start = time.Now() return srv.ListenAndServe() }) lifecycle.DeferErr(ctx, func() error { finish = time.Now() fmt.Println("shutting down http server") // use a background context because we already have a timeout and when // Defer funcs run, ctx is necessarily canceled. return srv.Shutdown(context.Background()) }) // Any panics in Go or Defer funcs will be passed to the goroutine that Wait // runs in, so it is possible to handle them like this defer func() { if r := recover(); r != nil { panic(r) // example, you probably want to do something else } }() // Then at the end of main(), or run() or however your application operates // // The returned err is the first non-nil error returned by any func // registered with Go or Defer, otherwise nil. if err := lifecycle.Wait(ctx); err != nil && err != context.DeadlineExceeded { log.Fatal(err) } // This is just to show that the server will run for at least `timeout` // before shutting down if finish.Sub(start) < timeout { log.Fatal("didn't wait long enough to shutdown") } }
Output: shutting down http server
Index ¶
- func Defer(ctx context.Context, deferred ...func())
- func DeferCtxErr(ctx context.Context, deferred ...func(context.Context) error)
- func DeferErr(ctx context.Context, deferred ...func() error)
- func Exists(ctx context.Context) bool
- func Go(ctx context.Context, f ...func())
- func GoCtxErr(ctx context.Context, f ...func(ctx context.Context) error)
- func GoErr(ctx context.Context, f ...func() error)
- func New(ctx context.Context, opts ...Option) context.Context
- func Wait(ctx context.Context) error
- type ErrSignal
- type Option
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Defer ¶
Defer adds funcs that should be called after the Go funcs complete (either clean or with errors) or a signal is received
func DeferCtxErr ¶ added in v1.1.0
DeferCtxErr adds funcs, that take a context and return an error, that should be called after the Go funcs complete (either clean or with errors) or a signal is received. If any GoErr, GoCtxErr, DeferErr or DeferCtxErr func returns an error, only the first one will be returned by Wait()
func DeferErr ¶ added in v0.0.2
DeferErr adds funcs, that return errors, that should be called after the Go funcs complete (either clean or with errors) or a signal is received. If any GoErr, GoCtxErr, DeferErr or DeferCtxErr func returns an error, only the first one will be returned by Wait()
func GoCtxErr ¶ added in v1.1.0
GoCtxErr runs a function that takes a context and returns an error in a new goroutine. If any GoErr, GoCtxErr, DeferErr or DeferCtxErr func returns an error, only the first one will be returned by Wait()
func GoErr ¶ added in v0.0.2
GoErr runs a function that returns an error in a new goroutine. If any GoErr, GoCtxErr, DeferErr or DeferCtxErr func returns an error, only the first one will be returned by Wait()
func Wait ¶
Wait blocks until all go routines have been completed.
All funcs registered with Go and Defer _will_ complete under every circumstance except a panic
Funcs passed to Defer begin (and the context returned by New() is canceled) when any of:
- All funcs registered with Go complete successfully
- Any func registered with Go returns an error
- A signal is received (by default SIGINT or SIGTERM, but can be changed by WithSignals
Funcs registered with Go should stop and clean up when the context returned by New() is canceled. If the func accepts a context argument, it will be passed the context returned by New().
WithTimeout() can be used to set a maximum amount of time, starting with the context returned by New() is canceled, that Wait will wait before returning.
The returned err is the first non-nil error returned by any func registered with Go or Defer, otherwise nil.
Types ¶
type ErrSignal ¶
ErrSignal is returned by Wait if the reason it returned was because a signal was caught
type Option ¶
type Option func(*manager)
An Option is used to configure the lifecycle manager
func WithSignals ¶
WithSignals causes Handle to wait for Go funcs to finish, if WhenDone was used or until a signal is received. The signals it will wait for can be defined with WithSigs or will default to syscall.SIGINT and syscall.SIGTERM
func WithTimeout ¶
WithTimeout sets an upper limit for how much time Handle will wait to return. After the Go funcs finish, if WhenDone was used, or after a signal is received if WhenSignaled was used, this timer starts. From that point, Handle will return if any Go or Defer function takes longer than this value.