Module: EcfDgii::Polling
- Defined in:
- lib/ecf_dgii/polling.rb
Overview
Polling logic with exponential backoff.
Usage:
EcfDgii::Polling.poll_until_complete do
client.query_ecf(rnc, encf)
end
Constant Summary collapse
- TERMINAL_PROGRESS =
Terminal progress values matching the ECF API contract.
- "Finished" → ECF processing completed successfully - "Error" → ECF processing failed (throws EcfError in client) %w[Finished Error].freeze
Class Method Summary collapse
-
.poll_until_complete(options = nil) ⇒ Object
Poll a block until its result indicates completion, using exponential backoff.
Class Method Details
.poll_until_complete(options = nil) ⇒ Object
Poll a block until its result indicates completion, using exponential backoff.
58 59 60 61 62 63 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 |
# File 'lib/ecf_dgii/polling.rb', line 58 def self.poll_until_complete( = nil) opts = || PollingOptions.new delay = opts.initial_delay retries = 0 start_time = Process.clock_gettime(Process::CLOCK_MONOTONIC) loop do # Check cancellation before each iteration if opts.cancellation && opts.cancellation.call raise PollingTimeoutError, "Polling was cancelled" end result = yield progress = extract_progress(result) return result if TERMINAL_PROGRESS.include?(progress) retries += 1 if opts.max_retries > 0 && retries >= opts.max_retries raise PollingMaxRetriesError.new(opts.max_retries) end if opts.timeout && opts.timeout > 0 elapsed = Process.clock_gettime(Process::CLOCK_MONOTONIC) - start_time if elapsed >= opts.timeout raise PollingTimeoutError, "Polling timed out after #{opts.timeout}s (last progress: #{progress})" end end sleep(delay) delay = [delay * opts.backoff_multiplier, opts.max_delay].min end end |