...

Source file src/github.com/aws/smithy-go/waiter/waiter.go

Documentation: github.com/aws/smithy-go/waiter

     1  package waiter
     2  
     3  import (
     4  	"fmt"
     5  	"math"
     6  	"time"
     7  
     8  	"github.com/aws/smithy-go/rand"
     9  )
    10  
    11  // ComputeDelay computes delay between waiter attempts. The function takes in a current attempt count,
    12  // minimum delay, maximum delay, and remaining wait time for waiter as input. The inputs minDelay and maxDelay
    13  // must always be greater than 0, along with minDelay lesser than or equal to maxDelay.
    14  //
    15  // Returns the computed delay and if next attempt count is possible within the given input time constraints.
    16  // Note that the zeroth attempt results in no delay.
    17  func ComputeDelay(attempt int64, minDelay, maxDelay, remainingTime time.Duration) (delay time.Duration, err error) {
    18  	// zeroth attempt, no delay
    19  	if attempt <= 0 {
    20  		return 0, nil
    21  	}
    22  
    23  	// remainingTime is zero or less, no delay
    24  	if remainingTime <= 0 {
    25  		return 0, nil
    26  	}
    27  
    28  	// validate min delay is greater than 0
    29  	if minDelay == 0 {
    30  		return 0, fmt.Errorf("minDelay must be greater than zero when computing Delay")
    31  	}
    32  
    33  	// validate max delay is greater than 0
    34  	if maxDelay == 0 {
    35  		return 0, fmt.Errorf("maxDelay must be greater than zero when computing Delay")
    36  	}
    37  
    38  	// Get attempt ceiling to prevent integer overflow.
    39  	attemptCeiling := (math.Log(float64(maxDelay/minDelay)) / math.Log(2)) + 1
    40  
    41  	if attempt > int64(attemptCeiling) {
    42  		delay = maxDelay
    43  	} else {
    44  		// Compute exponential delay based on attempt.
    45  		ri := 1 << uint64(attempt-1)
    46  		// compute delay
    47  		delay = minDelay * time.Duration(ri)
    48  	}
    49  
    50  	if delay != minDelay {
    51  		// randomize to get jitter between min delay and delay value
    52  		d, err := rand.CryptoRandInt63n(int64(delay - minDelay))
    53  		if err != nil {
    54  			return 0, fmt.Errorf("error computing retry jitter, %w", err)
    55  		}
    56  
    57  		delay = time.Duration(d) + minDelay
    58  	}
    59  
    60  	// check if this is the last attempt possible and compute delay accordingly
    61  	if remainingTime-delay <= minDelay {
    62  		delay = remainingTime - minDelay
    63  	}
    64  
    65  	return delay, nil
    66  }
    67  

View as plain text