Class: SidekiqUniqueJobs::TimerTask
- Inherits:
-
Concurrent::RubyExecutorService
- Object
- Concurrent::RubyExecutorService
- SidekiqUniqueJobs::TimerTask
- Includes:
- Concurrent::Concern::Dereferenceable, Concurrent::Concern::Observable
- Defined in:
- lib/sidekiq_unique_jobs/timer_task.rb
Overview
A very common concurrency pattern is to run a thread that performs a task at
regular intervals. The thread that performs the task sleeps for the given
interval then wakes up and performs the task. Lather, rinse, repeat... This
pattern causes two problems. First, it is difficult to test the business
logic of the task because the task itself is tightly coupled with the
concurrency logic. Second, an exception raised while performing the task can
cause the entire thread to abend. In a long-running application where the
task thread is intended to run for days/weeks/years a crashed task thread
can pose a significant problem. TimerTask alleviates both problems.
When a TimerTask is launched it starts a thread for monitoring the
execution interval. The TimerTask thread does not perform the task,
however. Instead, the TimerTask launches the task on a separate thread.
Should the task experience an unrecoverable crash only the task thread will
crash. This makes the TimerTask very fault tolerant. Additionally, the
TimerTask thread can respond to the success or failure of the task,
performing logging or ancillary operations.
One other advantage of TimerTask is that it forces the business logic to
be completely decoupled from the concurrency logic. The business logic can
be tested separately then passed to the TimerTask for scheduling and
running.
In some cases it may be necessary for a TimerTask to affect its own
execution cycle. To facilitate this, a reference to the TimerTask instance
is passed as an argument to the provided block every time the task is
executed.
The TimerTask class includes the Dereferenceable mixin module so the
result of the last execution is always available via the #value method.
Dereferencing options can be passed to the TimerTask during construction or
at any later time using the #set_deref_options method.
TimerTask supports notification through the Ruby standard library
Observable module. On execution the TimerTask will notify the observers
with three arguments: time of execution, the result of the block (or nil on
failure), and any raised exceptions (or nil on success).
Constant Summary collapse
- EXECUTION_INTERVAL =
Default
:execution_intervalin seconds. 60- TIMEOUT_INTERVAL =
Default
:timeout_intervalin seconds. 30
Instance Attribute Summary collapse
-
#execution_interval ⇒ Fixnum
Number of seconds after the task completes before the task is performed again.
Class Method Summary collapse
-
.execute(opts = {}) {|task| ... } ⇒ TimerTask
Create and execute a new
TimerTask.
Instance Method Summary collapse
-
#execute ⇒ TimerTask
Execute a previously created
TimerTask. -
#initialize(opts = {}) {|task| ... } ⇒ TimerTask
constructor
Create a new TimerTask with the given task and configuration.
-
#running? ⇒ Boolean
Is the executor running?.
Constructor Details
#initialize(opts = {}) {|task| ... } ⇒ TimerTask
Create a new TimerTask with the given task and configuration.
181 182 183 184 185 186 |
# File 'lib/sidekiq_unique_jobs/timer_task.rb', line 181 def initialize(opts = {}, &task) raise ArgumentError, "no block given" unless task super opts end |
Instance Attribute Details
#execution_interval ⇒ Fixnum
Returns Number of seconds after the task completes before the task is performed again.
232 233 234 |
# File 'lib/sidekiq_unique_jobs/timer_task.rb', line 232 def execution_interval synchronize { @execution_interval } end |
Class Method Details
Instance Method Details
#execute ⇒ TimerTask
Execute a previously created TimerTask.
208 209 210 211 212 213 214 215 216 |
# File 'lib/sidekiq_unique_jobs/timer_task.rb', line 208 def execute synchronize do if @running.false? @running.make_true schedule_next_task(@run_now ? 0 : @execution_interval) end end self end |
#running? ⇒ Boolean
Is the executor running?
191 192 193 |
# File 'lib/sidekiq_unique_jobs/timer_task.rb', line 191 def running? @running.true? end |