class GoodJob::Poller

Pollers regularly wake up execution threads to check for new work.

Constants

DEFAULT_TIMER_OPTIONS

Defaults for instance of Concurrent::TimerTask. The timer controls how and when sleeping threads check for new work.

TIMEOUT_INTERVAL

Attributes

recipients[R]

List of recipients that will receive notifications. @return [Array<#call, Array(Object, Symbol)>]

timer[R]

@return [Concurrent::TimerTask]

Public Class Methods

from_configuration(configuration) click to toggle source

Creates GoodJob::Poller from a GoodJob::Configuration instance. @param configuration [GoodJob::Configuration] @return [GoodJob::Poller]

   # File lib/good_job/poller.rb
28 def self.from_configuration(configuration)
29   GoodJob::Poller.new(poll_interval: configuration.poll_interval)
30 end
new(*recipients, poll_interval: nil) click to toggle source

@param recipients [Array<Proc, call, Array(Object, Symbol)>] @param poll_interval [Integer, nil] number of seconds between polls

   # File lib/good_job/poller.rb
38 def initialize(*recipients, poll_interval: nil)
39   @recipients = Concurrent::Array.new(recipients)
40 
41   @timer_options = DEFAULT_TIMER_OPTIONS.dup
42   @timer_options[:execution_interval] = poll_interval if poll_interval.present?
43 
44   self.class.instances << self
45 
46   create_timer
47 end

Public Instance Methods

restart(timeout: -1) click to toggle source

Restart the poller. When shutdown, start; or shutdown and start. @param timeout [Numeric, nil] Seconds to wait; shares same values as {#shutdown}. @return [void]

   # File lib/good_job/poller.rb
82 def restart(timeout: -1)
83   shutdown(timeout: timeout) if running?
84   create_timer
85 end
shutdown(timeout: -1) click to toggle source

Shut down the poller. Use {#shutdown?} to determine whether threads have stopped. @param timeout [nil, Numeric] Seconds to wait for active threads.

* +nil+, the scheduler will trigger a shutdown but not wait for it to complete.
* +-1+, the scheduler will wait until the shutdown is complete.
* +0+, the scheduler will immediately shutdown and stop any threads.
* A positive number will wait that many seconds before stopping any remaining active threads.

@return [void]

   # File lib/good_job/poller.rb
67 def shutdown(timeout: -1)
68   return if timer.nil? || timer.shutdown?
69 
70   timer.shutdown if timer.running?
71 
72   if timer.shuttingdown? && timeout # rubocop:disable Style/GuardClause
73     timer_wait = timeout.negative? ? nil : timeout
74     timer.kill unless timer.wait_for_termination(timer_wait)
75   end
76 end
shutdown?() click to toggle source

Tests whether the timer is shutdown. @return [true, false, nil]

   # File lib/good_job/poller.rb
55 def shutdown?
56   timer ? timer.shutdown? : true
57 end
timer_observer(time, executed_task, thread_error) click to toggle source

Invoked on completion of TimerTask task. @!visibility private @param time [Integer] @param executed_task [Object, nil] @param thread_error [Exception, nil] @return [void]

   # File lib/good_job/poller.rb
93 def timer_observer(time, executed_task, thread_error)
94   GoodJob.on_thread_error.call(thread_error) if thread_error && GoodJob.on_thread_error.respond_to?(:call)
95   ActiveSupport::Notifications.instrument("finished_timer_task", { result: executed_task, error: thread_error, time: time })
96 end

Private Instance Methods

create_timer() click to toggle source

@return [void]

    # File lib/good_job/poller.rb
104 def create_timer
105   return if @timer_options[:execution_interval] <= 0
106 
107   @timer = Concurrent::TimerTask.new(@timer_options) do
108     recipients.each do |recipient|
109       target, method_name = recipient.is_a?(Array) ? recipient : [recipient, :call]
110       target.send(method_name)
111     end
112   end
113   @timer.add_observer(self, :timer_observer)
114   @timer.execute
115 end