Class: SSE::Impl::Backoff

Inherits:
Object
  • Object
show all
Defined in:
lib/ld-eventsource/impl/backoff.rb

Overview

A simple backoff algorithm that can reset itself after a given interval has passed without errors. A random jitter of up to -50% is applied to each interval.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(base_interval, max_interval, reconnect_reset_interval: 60) ⇒ Backoff

Constructs a backoff counter.

Parameters:

  • base_interval (Float)

    the minimum value

  • max_interval (Float)

    the maximum value

  • reconnect_reset_interval (Float) (defaults to: 60)

    the interval will be reset to the minimum if this number of seconds elapses between the last call to #mark_success and the next call to #next_interval



17
18
19
20
21
22
23
24
# File 'lib/ld-eventsource/impl/backoff.rb', line 17

def initialize(base_interval, max_interval, reconnect_reset_interval: 60)
  @base_interval = base_interval
  @max_interval = max_interval
  @reconnect_reset_interval = reconnect_reset_interval
  @attempts = 0
  @last_good_time = nil
  @jitter_rand = Random.new
end

Instance Attribute Details

#base_intervalObject

The minimum value for the backoff interval.



29
30
31
# File 'lib/ld-eventsource/impl/backoff.rb', line 29

def base_interval
  @base_interval
end

Instance Method Details

#mark_successObject

Marks the current time as being the beginning of a valid connection state, resetting the timer that measures how long the state has been valid.



51
52
53
# File 'lib/ld-eventsource/impl/backoff.rb', line 51

def mark_success
  @last_good_time = Time.now.to_f
end

#next_intervalFloat

Computes the next interval value.

Returns:

  • (Float)

    the next interval in seconds



36
37
38
39
40
41
42
43
44
45
# File 'lib/ld-eventsource/impl/backoff.rb', line 36

def next_interval
  if !@last_good_time.nil?
    good_duration = Time.now.to_f - @last_good_time
    @attempts = 0 if good_duration >= @reconnect_reset_interval
  end
  @last_good_time = nil
  target = ([@base_interval * (2 ** @attempts), @max_interval].min).to_f
  @attempts += 1
  (target / 2) + @jitter_rand.rand(target / 2)
end