1// Copyright 2012-present Oliver Eilhard. All rights reserved. 2// Use of this source code is governed by a MIT-license. 3// See http://olivere.mit-license.org/license.txt for details. 4 5// This file is based on code (c) 2014 Cenk Altı and governed by the MIT license. 6// See https://github.com/cenkalti/backoff for original source. 7 8package elastic 9 10import "time" 11 12// An Operation is executing by Retry() or RetryNotify(). 13// The operation will be retried using a backoff policy if it returns an error. 14type Operation func() error 15 16// Notify is a notify-on-error function. It receives error returned 17// from an operation. 18// 19// Notice that if the backoff policy stated to stop retrying, 20// the notify function isn't called. 21type Notify func(error) 22 23// Retry the function f until it does not return error or BackOff stops. 24// f is guaranteed to be run at least once. 25// It is the caller's responsibility to reset b after Retry returns. 26// 27// Retry sleeps the goroutine for the duration returned by BackOff after a 28// failed operation returns. 29func Retry(o Operation, b Backoff) error { return RetryNotify(o, b, nil) } 30 31// RetryNotify calls notify function with the error and wait duration 32// for each failed attempt before sleep. 33func RetryNotify(operation Operation, b Backoff, notify Notify) error { 34 var err error 35 var wait time.Duration 36 var retry bool 37 var n int 38 39 for { 40 if err = operation(); err == nil { 41 return nil 42 } 43 44 n++ 45 wait, retry = b.Next(n) 46 if !retry { 47 return err 48 } 49 50 if notify != nil { 51 notify(err) 52 } 53 54 time.Sleep(wait) 55 } 56} 57