Class ExponentialBackOff

java.lang.Object
com.google.api.client.util.ExponentialBackOff
All Implemented Interfaces:
BackOff

public class ExponentialBackOff extends Object implements BackOff
Implementation of BackOff that increases the back off period for each retry attempt using a randomization function that grows exponentially.

nextBackOffMillis() is calculated using the following formula:

 randomized_interval =
 retry_interval * (random value in range [1 - randomization_factor, 1 + randomization_factor])
 

In other words nextBackOffMillis() will range between the randomization factor percentage below and above the retry interval. For example, using 2 seconds as the base retry interval and 0.5 as the randomization factor, the actual back off period used in the next retry attempt will be between 1 and 3 seconds.

Note: max_interval caps the retry_interval and not the randomized_interval.

If the time elapsed since an ExponentialBackOff instance is created goes past the max_elapsed_time then the method nextBackOffMillis() starts returning BackOff.STOP. The elapsed time can be reset by calling reset().

Example: The default retry_interval is .5 seconds, default randomization_factor is 0.5, default multiplier is 1.5 and the default max_interval is 1 minute. For 10 tries the sequence will be (values in seconds) and assuming we go over the max_elapsed_time on the 10th try:

 request#     retry_interval     randomized_interval

 1             0.5                [0.25,   0.75]
 2             0.75               [0.375,  1.125]
 3             1.125              [0.562,  1.687]
 4             1.687              [0.8435, 2.53]
 5             2.53               [1.265,  3.795]
 6             3.795              [1.897,  5.692]
 7             5.692              [2.846,  8.538]
 8             8.538              [4.269, 12.807]
 9            12.807              [6.403, 19.210]
 10           19.210              BackOff.STOP
 

Implementation is not thread-safe.

Since:
1.15
  • Field Details

    • DEFAULT_INITIAL_INTERVAL_MILLIS

      public static final int DEFAULT_INITIAL_INTERVAL_MILLIS
      The default initial interval value in milliseconds (0.5 seconds).
      See Also:
    • DEFAULT_RANDOMIZATION_FACTOR

      public static final double DEFAULT_RANDOMIZATION_FACTOR
      The default randomization factor (0.5 which results in a random period ranging between 50% below and 50% above the retry interval).
      See Also:
    • DEFAULT_MULTIPLIER

      public static final double DEFAULT_MULTIPLIER
      The default multiplier value (1.5 which is 50% increase per back off).
      See Also:
    • DEFAULT_MAX_INTERVAL_MILLIS

      public static final int DEFAULT_MAX_INTERVAL_MILLIS
      The default maximum back off time in milliseconds (1 minute).
      See Also:
    • DEFAULT_MAX_ELAPSED_TIME_MILLIS

      public static final int DEFAULT_MAX_ELAPSED_TIME_MILLIS
      The default maximum elapsed time in milliseconds (15 minutes).
      See Also:
    • currentIntervalMillis

      private int currentIntervalMillis
      The current retry interval in milliseconds.
    • initialIntervalMillis

      private final int initialIntervalMillis
      The initial retry interval in milliseconds.
    • randomizationFactor

      private final double randomizationFactor
      The randomization factor to use for creating a range around the retry interval.

      A randomization factor of 0.5 results in a random period ranging between 50% below and 50% above the retry interval.

    • multiplier

      private final double multiplier
      The value to multiply the current interval with for each retry attempt.
    • maxIntervalMillis

      private final int maxIntervalMillis
      The maximum value of the back off period in milliseconds. Once the retry interval reaches this value it stops increasing.
    • startTimeNanos

      long startTimeNanos
      The system time in nanoseconds. It is calculated when an ExponentialBackOffPolicy instance is created and is reset when reset() is called.
    • maxElapsedTimeMillis

      private final int maxElapsedTimeMillis
      The maximum elapsed time after instantiating ExponentialBackOff or calling reset() after which nextBackOffMillis() returns BackOff.STOP.
    • nanoClock

      private final NanoClock nanoClock
      Nano clock.
  • Constructor Details

  • Method Details

    • reset

      public final void reset()
      Sets the interval back to the initial retry interval and restarts the timer.
      Specified by:
      reset in interface BackOff
    • nextBackOffMillis

      public long nextBackOffMillis() throws IOException
      Gets the number of milliseconds to wait before retrying the operation or BackOff.STOP to indicate that no retries should be made.

      Example usage:

       long backOffMillis = backoff.nextBackOffMillis();
       if (backOffMillis == Backoff.STOP) {
       // do not retry operation
       } else {
       // sleep for backOffMillis milliseconds and retry operation
       }
       

      This method calculates the next back off interval using the formula: randomized_interval = retry_interval +/- (randomization_factor * retry_interval)

      Subclasses may override if a different algorithm is required.

      Specified by:
      nextBackOffMillis in interface BackOff
      Throws:
      IOException
    • getRandomValueFromInterval

      static int getRandomValueFromInterval(double randomizationFactor, double random, int currentIntervalMillis)
      Returns a random value from the interval [randomizationFactor * currentInterval, randomizationFactor * currentInterval].
    • getInitialIntervalMillis

      public final int getInitialIntervalMillis()
      Returns the initial retry interval in milliseconds.
    • getRandomizationFactor

      public final double getRandomizationFactor()
      Returns the randomization factor to use for creating a range around the retry interval.

      A randomization factor of 0.5 results in a random period ranging between 50% below and 50% above the retry interval.

    • getCurrentIntervalMillis

      public final int getCurrentIntervalMillis()
      Returns the current retry interval in milliseconds.
    • getMultiplier

      public final double getMultiplier()
      Returns the value to multiply the current interval with for each retry attempt.
    • getMaxIntervalMillis

      public final int getMaxIntervalMillis()
      Returns the maximum value of the back off period in milliseconds. Once the current interval reaches this value it stops increasing.
    • getMaxElapsedTimeMillis

      public final int getMaxElapsedTimeMillis()
      Returns the maximum elapsed time in milliseconds.

      If the time elapsed since an ExponentialBackOff instance is created goes past the max_elapsed_time then the method nextBackOffMillis() starts returning BackOff.STOP. The elapsed time can be reset by calling reset().

    • getElapsedTimeMillis

      public final long getElapsedTimeMillis()
      Returns the elapsed time in milliseconds since an ExponentialBackOff instance is created and is reset when reset() is called.

      The elapsed time is computed using System.nanoTime().

    • incrementCurrentInterval

      private void incrementCurrentInterval()
      Increments the current interval by multiplying it with the multiplier.