Sha256: 111507f0428f707779b5d11719cdcc5f1d4dafc0b39665529e792851bbe1c72d

Contents?: true

Size: 1.3 KB

Versions: 22

Compression:

Stored size: 1.3 KB

Contents

# frozen_string_literal: true

module PlainApm
  class Backoff
    ##
    # Exponential backoff with jitter.

    DEFAULT_BASE_SECONDS = 1.5
    DEFAULT_MAX_RETRIES = 10 # sum_0^10 1.5 ** k ~ 170s
    DEFAULT_JITTER_MULTIPLIER = 0.2 # % of the current retry interval

    ##
    # @param base_seconds [Integer] base of the exponential retry.
    # @param max_retries [Integer] maximum retries to perform.
    # @param jitter_multiplier [Float] % of the current retry interval to use for jitter.
    def initialize(base_seconds: nil, max_retries: nil, jitter_multiplier: nil)
      @base_seconds = base_seconds || DEFAULT_BASE_SECONDS
      @max_retries = max_retries || DEFAULT_MAX_RETRIES
      @jitter_multiplier = jitter_multiplier || DEFAULT_JITTER_MULTIPLIER
    end

    ##
    # @param retries [Integer] Number of current retry attempts.
    #
    # @return [Integer|nil] Amount of time slept, or nil if out of retries.
    def delay_time(retries:)
      return if retries >= max_retries

      base_interval = (base_seconds**retries)
      jitter_interval = base_interval * jitter_multiplier

      # The random factor is never -1, but that shouldn't be an issue.
      base_interval + jitter_interval * (1.0 - 2.0 * rand)
    end

    private

    attr_reader :base_seconds, :max_retries, :jitter_multiplier
  end
end

Version data entries

22 entries across 22 versions & 1 rubygems

Version Path
plain_apm-0.2.8 lib/plain_apm/backoff.rb
plain_apm-0.2.6 lib/plain_apm/backoff.rb