package processimport ()// Parallel returns a Runnable instance that starts and runs processes in// parallel. If no processes are given, it returns Nop instance.//// The resulting Runnable calls callback after all process dependencies are// successfully started. If any dependecy fails to start, processes that have// already started are gracefully stopped. If any dependency fails before the// main callback returns, the context passed to callback is canceled and all// processes are gracefully stopped (unless the parent context has expired).//// The callbacks of dependencies return after the callback of the resulting// dependent process. Run returns callback error if it is not nil, otherwise it// returns combined errors from dependencies.func ( ...Runnable) Runnable {switchlen() {case0:returnNop()case1:return [0] }return &groupRunnable{deps: ,exec: task.ParallelExecutor(), }}// Sequential returns a Runnable instance with the same guarantees as the// Parallel function, but starts and stops processes in sequential order.func ( ...Runnable) Runnable {switchlen() {case0:returnNop()case1:return [0] }return &groupRunnable{deps: ,exec: task.SequentialExecutor(), }}typegroupRunnablestruct {deps []Runnableexectask.Executor}func ( *groupRunnable) ( context.Context, Callback) error {varsync.Oncevarsync.WaitGroup .Add(1)// fgctx is passed to callback and cancel is used from child // process below to cancel callback invocation after startup. , := context.WithCancel()defer () := func( context.Context, Callback) error { := ()// Propagate process shutdown to main callback and wait // for it to return before exiting. () .Wait()return } := len(.deps) := make([]*Process, ) := make([]task.Task, 2*) := [0* : 1*] := [1* : 2*]for , := range .deps { := NewProcess(, Chain(, RunnableFunc())) [] = [] = func( context.Context) error { := .Start()if == nil {returnnil }// If startup failed, we do not invoke callback. // Unblock callbacks for process dependencies // that have already started. .Do(.Done)return } [] = func( context.Context) error {// We get either ErrProcessInvalidState or p.Err // from Stop so it is safe to ignore error here. _ = .Stop()return .Err() } } := .exec.Execute(, task.CancelOnError(), ...)varerrorif == nil { = ()// Main callback has returned, unblock callbacks for // dependencies. .Done() } := .exec.Execute(, task.NeverCancel(), ...)if != nil {return }return}
The pages are generated with Goldsv0.4.9. (GOOS=linux GOARCH=amd64)