Source File
task.go
Belonging Package
go.pact.im/x/process
package processimport ()// Leaf converts a “leaf” function to a process entrypoint with callback. It// accepts an optional gracefulStop function to perform graceful shutdown. If// the function is nil, the process will be terminated by context cancellation// instead.//// The resulting [Runner] returns first non-nil error from functions in the// following order: callback, gracefulStop, runInForeground. That is, if both// callback and gracefulStop return a non-nil error, the latter is ignored.//// Example (HTTP)://// var lis net.Listener// var srv *http.Server//// process.Leaf(// func(_ context.Context) error {// err := srv.Serve(lis)// if errors.Is(err, http.ErrServerClosed) {// return nil// }// return err// },// func(ctx context.Context) error {// err := srv.Shutdown(ctx)// if err != nil {// return srv.Close()// }// return nil// },// )//// Example (gRPC)://// var lis net.Listener// var srv *grpc.Server//// process.Leaf(// func(_ context.Context) error {// return srv.Serve(lis)// },// func(ctx context.Context) error {// done := make(chan struct{})// go func() {// srv.GracefulStop()// close(done)// }()// select {// case <-ctx.Done():// srv.Stop()// <-done// case <-done:// }// return nil// },// )//// Alternatively, use [go.pact.im/x/httpprocess] package for HTTP and// [go.pact.im/x/grpcprocess] for gRPC.func (, func( context.Context) error) Runner {return &leafRunner{, }}type leafRunner struct {runInForeground func(ctx context.Context) errorgracefulStop func(ctx context.Context) error}func ( *leafRunner) ( context.Context, Callback) error {, := context.WithCancel()defer ()var sync.WaitGroup.Add(1)var errorgo func() {defer .Done()= .runInForeground()() // cancel callback}():= ()var errorif .gracefulStop != nil {= .gracefulStop()}().Wait()switch {case != nil:returncase != nil:return}return}// StartStop returns a [Runner] instance for the pair of start/stop functions.// The stop function should perform a graceful shutdown until a context expires,// then proceed with a forced shutdown.//// The resulting [Runner] returns either start error or the first non-nil error// from callback and stop functions. If both callback and stop return a non-nil// error, the latter is ignored.func (, func( context.Context) error) Runner {return &startStopRunner{, }}type startStopRunner struct {startInBackground func(ctx context.Context) errorgracefulStop func(ctx context.Context) error}func ( *startStopRunner) ( context.Context, Callback) error {if := .startInBackground(); != nil {return}:= ()if := .gracefulStop(); != nil && == nil {return}return}
The pages are generated with Golds v0.7.6. (GOOS=linux GOARCH=amd64)