Class: PollerBear::Base

Inherits:
Object
  • Object
show all
Defined in:
lib/poller_bear/base.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(**options) ⇒ Base

Returns a new instance of Base.

Parameters:

  • options (Hash)

Options Hash (**options):

  • :every (Float, Symbol)

    The interval in seconds between each poll or :exponential for exponential backoff (default: 1.0)

  • :for (Float)

    The total duration in seconds to poll for (default: nil, meaning no time limit)

  • :max_retries (Integer)

    The maximum number of retries on failure (default: nil, meaning unlimited)

  • :stop_when (Proc)

    A lambda that takes the result and attempt number, and returns true to stop polling (default: true, meaning stop after the first attempt if no errors)

  • :retry_on_exceptions (Boolean, Array<StandardError>)

    Whether to retry on exceptions raised in the block.



20
21
22
23
24
25
26
27
28
# File 'lib/poller_bear/base.rb', line 20

def initialize(**options)
  @interval = options.fetch(:every, 1.0).then { |val| val.respond_to?(:to_f) ? val.to_f : val }
  @end_time = options.fetch(:for, nil)&.then { |duration| Time.now + duration.to_f }
  @max_retries = options.fetch(:max_retries, nil)
  @stop_when = options.fetch(:stop_when, -> (_result, _attempt) { true })
  @retry_on_exceptions = options.fetch(:retry_on_exceptions, false)

  warn_on_infinite_polling if @end_time.nil? && options[:stop_when].nil?
end

Instance Attribute Details

#end_timeObject (readonly)

Returns the value of attribute end_time.



7
8
9
# File 'lib/poller_bear/base.rb', line 7

def end_time
  @end_time
end

#intervalObject (readonly)

Returns the value of attribute interval.



7
8
9
# File 'lib/poller_bear/base.rb', line 7

def interval
  @interval
end

#max_retriesObject (readonly)

Returns the value of attribute max_retries.



7
8
9
# File 'lib/poller_bear/base.rb', line 7

def max_retries
  @max_retries
end

#retry_on_exceptionsObject (readonly)

Returns the value of attribute retry_on_exceptions.



7
8
9
# File 'lib/poller_bear/base.rb', line 7

def retry_on_exceptions
  @retry_on_exceptions
end

#stop_whenObject (readonly)

Returns the value of attribute stop_when.



7
8
9
# File 'lib/poller_bear/base.rb', line 7

def stop_when
  @stop_when
end

Instance Method Details

#pollObject

Raises:

  • (ArgumentError)


30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/poller_bear/base.rb', line 30

def poll(&)
  raise ArgumentError, "A block must be provided to poll" unless block_given?
  attempts = max_retries ? max_retries : Float::INFINITY
  error = nil

  1.upto(attempts) do |attempt|
    if end_time && Time.now >= end_time
      raise TimeoutError.new("Polling timed out"), cause: error
    end

    result = yield(attempt)
    return result if stop_when && stop_when.call(result, attempt)

    sleep_interval(attempt)
  rescue StandardError => error
    if should_retry_on_exception?(error)
      sleep_interval(attempt)
      next
    else
      raise error
    end
  end

  raise MaxRetriesExceededError.new("Polled maximum number of retries"), cause: error
end