github.com/vmg/backoff@v1.0.0/retry.go (about) 1 package backoff 2 3 import "time" 4 5 // An Operation is executing by Retry() or RetryNotify(). 6 // The operation will be retried using a backoff policy if it returns an error. 7 type Operation func() error 8 9 // Notify is a notify-on-error function. It receives an operation error and 10 // backoff delay if the operation failed (with an error). 11 // 12 // NOTE that if the backoff policy stated to stop retrying, 13 // the notify function isn't called. 14 type Notify func(error, time.Duration) 15 16 // Retry the function f until it does not return error or BackOff stops. 17 // f is guaranteed to be run at least once. 18 // It is the caller's responsibility to reset b after Retry returns. 19 // 20 // Retry sleeps the goroutine for the duration returned by BackOff after a 21 // failed operation returns. 22 func Retry(o Operation, b BackOff) error { return RetryNotify(o, b, nil) } 23 24 // RetryNotify calls notify function with the error and wait duration 25 // for each failed attempt before sleep. 26 func RetryNotify(operation Operation, b BackOff, notify Notify) error { 27 var err error 28 var next time.Duration 29 30 b.Reset() 31 for { 32 if err = operation(); err == nil { 33 return nil 34 } 35 36 if next = b.NextBackOff(); next == Stop { 37 return err 38 } 39 40 if notify != nil { 41 notify(err, next) 42 } 43 44 time.Sleep(next) 45 } 46 }