github.com/telepresenceio/telepresence/v2@v2.20.0-pro.6.0.20240517030216-236ea954e789/pkg/client/ensured_state.go (about) 1 package client 2 3 import ( 4 "context" 5 "fmt" 6 "time" 7 ) 8 9 type ( 10 Prolog func(context.Context) (acquired bool, err error) 11 Action func(context.Context) error 12 ) 13 14 // WithEnsuredState calls prolog, and if that was successful, calls act. If epilog is not nil, it is guaranteed 15 // to be called when prolog returns true. 16 func WithEnsuredState(ctx context.Context, prolog Prolog, action, epilog Action) error { 17 wasAcquired, err := prolog(ctx) 18 if err != nil { 19 return err 20 } 21 if wasAcquired && epilog != nil { 22 defer func() { 23 // The context might have been cancelled, so we use the original context 24 // without cancellation, but with a deactivation timeout of 10 seconds. 25 ctx, cancel := context.WithTimeout(context.WithoutCancel(ctx), 10*time.Second) 26 defer cancel() 27 if cerr := epilog(ctx); cerr != nil { 28 if err == nil { 29 err = cerr 30 } else { 31 err = fmt.Errorf("%w\n%v", err, cerr) 32 } 33 } 34 }() 35 } 36 if action != nil { 37 err = action(ctx) 38 } 39 return err 40 }