Class: InfluxDB2::WriteRetry

Inherits:
Object
  • Object
show all
Defined in:
lib/influxdb2/client/write_retry.rb

Overview

Exponential random write retry.

Instance Method Summary collapse

Constructor Details

#initialize(options = {}) ⇒ WriteRetry

Returns a new instance of WriteRetry.

Parameters:

  • options (Hash) (defaults to: {})

    the retry options.

Options Hash (options):

  • :max_retries (Integer) — default: 5

    The maximum number of times to run the block.

  • :retry_interval (Integer) — default: 5000

    number of milliseconds to retry unsuccessful write.

  • :max_retry_delay (Integer) — default: 125_000

    maximum delay when retrying write in milliseconds.

  • :max_retry_time (Integer) — default: 180_000

    maximum total retry timeout in milliseconds.

  • :exponential_base (Integer)

    base for the exponential retry delay

  • :jitter_delay (Integer)

    random milliseconds added to write interval

[View source]

33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/influxdb2/client/write_retry.rb', line 33

def initialize(options = {})
  @api_client = options[:api_client]
  @max_retries = options[:max_retries] || 5
  raise "#{@error_msg_prefix} :max_retries must be greater than 0." unless @max_retries > 0

  @retry_interval = options[:retry_interval] || 5_000
  @max_retry_delay = options[:max_retry_delay] || 125_000
  @max_retry_time = options[:max_retry_time] || 180_000
  @exponential_base = options[:exponential_base] || 2
  @jitter_interval = options[:jitter_interval] || 0
  raise "#{@error_msg_prefix} :retry_interval cannot be greater than :max_retry_delay." if
    @retry_interval > @max_retry_delay
end

Instance Method Details

#_connection_error(error) ⇒ Object

[View source]

100
101
102
# File 'lib/influxdb2/client/write_retry.rb', line 100

def _connection_error(error)
  InfluxError::HTTP_ERRORS.any? { |c| error.instance_of? c }
end

#get_backoff_time(attempts) ⇒ Object

[View source]

47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/influxdb2/client/write_retry.rb', line 47

def get_backoff_time(attempts)
  range_start = @retry_interval
  range_stop = @retry_interval * @exponential_base

  i = 1
  while i < attempts
    i += 1
    range_start = range_stop
    range_stop *= @exponential_base
    break if range_stop > @max_retry_delay
  end

  range_stop = @max_retry_delay if range_stop > @max_retry_delay
  range_start + (range_stop - range_start) * rand
end

#retryObject

Runs the supplied code block with a exponential backoff retry strategy.

[View source]

64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'lib/influxdb2/client/write_retry.rb', line 64

def retry
  raise "#{@error_msg_prefix} must be passed a block" unless block_given?

  attempts = 0
  start_time = Time.now
  begin
    attempts += 1
    yield attempts
  rescue InfluxError => e
    if attempts > @max_retries
      @api_client.log(:error, 'Maximum retry attempts reached.')
      raise e
    end

    if (Time.now - start_time) * 1000 > @max_retry_time
      @api_client.log(:error, "Maximum retry time #{@max_retry_time} ms exceeded")
      raise e
    end

    raise e if (e.code.nil? || e.code.to_i < 429) && !_connection_error(e.original)

    timeout = if e.retry_after.nil? || e.retry_after.empty?
                get_backoff_time(attempts)
              else
                (e.retry_after.to_f * 1000) + @jitter_interval * rand
              end

    message = 'The retriable error occurred during writing of data. '\
"Reason: '#{e.message}'. Retry in: #{timeout.to_f / 1000}s."

    @api_client.log(:warn, message)
    sleep timeout / 1000
    retry
  end
end