// nolint:nilaway - the context timeout here is reported as an error, even though it is a by-the-doc example package utils import ( "context" "fmt" "time" ) // TimeoutPolicy is an interface for enforcing common timeout patterns type TimeoutPolicy time.Duration // ExecuteAction runs a function and returns an error if it hasn't returned // by the time specified by TimeoutPolicy func (tp *TimeoutPolicy) ExecuteAction(action func() error) error { ctx, cancel := context.WithTimeout(context.Background(), time.Duration(*tp)) defer cancel() // channel is buffered- this is important! c := make(chan error, 1) go func() { // this write is non-blocking as this goroutine has sole access to the channel c <- action() }() select { case err := <-c: return err case <-ctx.Done(): return fmt.Errorf("ActionTimedOutError") } }