github.com/celestiaorg/celestia-node@v0.15.0-beta.1/das/backoff.go (about) 1 package das 2 3 import ( 4 "time" 5 ) 6 7 var ( 8 // first retry attempt should happen after defaultBackoffInitialInterval 9 defaultBackoffInitialInterval = time.Minute 10 // next retry attempt will happen with delay of previous one multiplied by defaultBackoffMultiplier 11 defaultBackoffMultiplier = 4 12 // after defaultBackoffMaxRetryCount amount of attempts retry backoff interval will stop growing 13 // and each retry attempt will produce WARN log 14 defaultBackoffMaxRetryCount = 4 15 ) 16 17 // retryStrategy defines a backoff for retries. 18 type retryStrategy struct { 19 // attempts delays will follow durations stored in retryIntervals 20 retryIntervals []time.Duration 21 } 22 23 // newRetryStrategy creates and initializes a new retry backoff. 24 func newRetryStrategy(retryIntervals []time.Duration) retryStrategy { 25 return retryStrategy{retryIntervals: retryIntervals} 26 } 27 28 // nextRetry creates a retry attempt with a backoff delay based on the retry backoff. 29 // It takes the number of retry attempts and the time of the last attempt as inputs and returns a 30 // retry instance and a boolean value indicating whether the retries amount have exceeded. 31 func (s retryStrategy) nextRetry(lastRetry retryAttempt, lastAttempt time.Time, 32 ) (retry retryAttempt, retriesExceeded bool) { 33 lastRetry.count++ 34 35 if len(s.retryIntervals) == 0 { 36 return lastRetry, false 37 } 38 39 if lastRetry.count > len(s.retryIntervals) { 40 // try count exceeded backoff try limit 41 lastRetry.after = lastAttempt.Add(s.retryIntervals[len(s.retryIntervals)-1]) 42 return lastRetry, true 43 } 44 45 lastRetry.after = lastAttempt.Add(s.retryIntervals[lastRetry.count-1]) 46 return lastRetry, false 47 } 48 49 // exponentialBackoff generates an array of time.Duration values using an exponential growth 50 // multiplier. 51 func exponentialBackoff(baseInterval time.Duration, multiplier, amount int) []time.Duration { 52 backoff := make([]time.Duration, 0, amount) 53 next := baseInterval 54 for i := 0; i < amount; i++ { 55 backoff = append(backoff, next) 56 next *= time.Duration(multiplier) 57 } 58 return backoff 59 }