// Package tdsync contains some useful synchronization utilities.
package tdsync import ( ) // CancellableGroup is simple wrapper around // errgroup.Group to make group cancellation easier. // Unlike WaitGroup and errgroup.Group this is not allowed to use zero value. type CancellableGroup struct { cancel context.CancelFunc group *errgroup.Group ctx context.Context } // NewCancellableGroup creates new CancellableGroup. // // Example: // // g := NewCancellableGroup(ctx) // g.Go(func(ctx context.Context) error { // <-ctx.Done() // return ctx.Err() // }) // g.Cancel() // g.Wait() func ( context.Context) *CancellableGroup { , := context.WithCancel() , := errgroup.WithContext() return &CancellableGroup{ cancel: , group: , ctx: , } } // Go calls the given function in a new goroutine. // // The first call to return a non-nil error cancels the group; its error will be // returned by Wait. func ( *CancellableGroup) ( func( context.Context) error) { .group.Go(func() error { return (.ctx) }) } // Cancel cancels all goroutines in group. // // Note: context cancellation error will be returned by Wait(). func ( *CancellableGroup) () { .cancel() } // Wait blocks until all function calls from the Go method have returned, then // returns the first non-nil error (if any) from them. func ( *CancellableGroup) () error { return .group.Wait() }