module Datadog::Workers::IntervalLoop

Adds looping behavior to workers, with a sleep interval between each loop.

Constants

BACK_OFF_MAX
BACK_OFF_RATIO
BASE_INTERVAL

Attributes

loop_back_off_max[W]
loop_back_off_ratio[W]
loop_base_interval[W]

Public Class Methods

included(base) click to toggle source
# File lib/ddtrace/workers/loop.rb, line 11
def self.included(base)
  base.prepend(PrependedMethods)
end

Public Instance Methods

loop_back_off!() click to toggle source
# File lib/ddtrace/workers/loop.rb, line 72
def loop_back_off!
  self.loop_wait_time = [loop_wait_time * BACK_OFF_RATIO, BACK_OFF_MAX].min
end
loop_back_off?() click to toggle source

Should the loop “back off” when there's no work?

# File lib/ddtrace/workers/loop.rb, line 68
def loop_back_off?
  false
end
loop_back_off_max() click to toggle source
# File lib/ddtrace/workers/loop.rb, line 51
def loop_back_off_max
  @loop_back_off_max ||= BACK_OFF_MAX
end
loop_back_off_ratio() click to toggle source
# File lib/ddtrace/workers/loop.rb, line 47
def loop_back_off_ratio
  @loop_back_off_ratio ||= BACK_OFF_RATIO
end
loop_base_interval() click to toggle source
# File lib/ddtrace/workers/loop.rb, line 43
def loop_base_interval
  @loop_base_interval ||= BASE_INTERVAL
end
loop_wait_before_first_iteration?() click to toggle source

Should perform_loop just straight into work, or start by waiting?

The use case is if we want to report some information (like profiles) from time to time, we may not want to report empty/zero/some residual value immediately when the worker starts.

# File lib/ddtrace/workers/loop.rb, line 80
def loop_wait_before_first_iteration?
  false
end
loop_wait_time() click to toggle source
# File lib/ddtrace/workers/loop.rb, line 55
def loop_wait_time
  @loop_wait_time ||= loop_base_interval
end
loop_wait_time=(value) click to toggle source
# File lib/ddtrace/workers/loop.rb, line 59
def loop_wait_time=(value)
  @loop_wait_time = value
end
reset_loop_wait_time() click to toggle source
# File lib/ddtrace/workers/loop.rb, line 63
def reset_loop_wait_time
  self.loop_wait_time = loop_base_interval
end
run_loop?() click to toggle source
# File lib/ddtrace/workers/loop.rb, line 37
def run_loop?
  return false unless instance_variable_defined?(:@run_loop)

  @run_loop == true
end
stop_loop() click to toggle source
# File lib/ddtrace/workers/loop.rb, line 22
def stop_loop
  mutex.synchronize do
    return false unless run_loop?

    @run_loop = false
    shutdown.signal
  end

  true
end
work_pending?() click to toggle source
# File lib/ddtrace/workers/loop.rb, line 33
def work_pending?
  run_loop?
end

Protected Instance Methods

mutex() click to toggle source
# File lib/ddtrace/workers/loop.rb, line 91
def mutex
  @mutex ||= Mutex.new
end

Private Instance Methods

perform_loop() { || ... } click to toggle source
# File lib/ddtrace/workers/loop.rb, line 97
def perform_loop
  mutex.synchronize do
    @run_loop = true

    shutdown.wait(mutex, loop_wait_time) if loop_wait_before_first_iteration?
  end

  loop do
    if work_pending?
      # There's work to do...
      # Run the task
      yield

      # Reset the wait interval
      reset_loop_wait_time if loop_back_off?
    elsif loop_back_off?
      # There's no work to do...
      # Back off the wait interval a bit
      loop_back_off!
    end

    # Wait for an interval, unless shutdown has been signaled.
    mutex.synchronize do
      return unless run_loop? || work_pending?

      shutdown.wait(mutex, loop_wait_time) if run_loop?
    end
  end
end
shutdown() click to toggle source
# File lib/ddtrace/workers/loop.rb, line 127
def shutdown
  @shutdown ||= ConditionVariable.new
end