class NewRelic::Agent::WorkerLoop

A worker loop executes a set of registered tasks on a single thread. A task is a proc or block with a specified call period in seconds.

Attributes

iterations[R]
period[RW]
propagate_errors[RW]

Public Class Methods

new(opts = {}) click to toggle source

Optional argument :duration (in seconds) for how long the worker loop runs or :limit (integer) for max number of iterations

# File lib/new_relic/agent/worker_loop.rb, line 17
def initialize(opts = {})
  @should_run = true
  @next_invocation_time = Process.clock_gettime(Process::CLOCK_REALTIME)
  @period = 60.0
  @duration = opts[:duration]
  @limit = opts[:limit]
  @iterations = 0
  @propagate_errors = opts.fetch(:propagate_errors, false)
  @deadline = nil
end

Public Instance Methods

keep_running?() click to toggle source

a simple accessor for @should_run

# File lib/new_relic/agent/worker_loop.rb, line 62
def keep_running?
  @should_run && under_duration? && under_limit?
end
run(period = nil, &block) click to toggle source

Run infinitely, calling the registered tasks at their specified call periods. The caller is responsible for creating the thread that runs this worker loop. This will run the task immediately.

# File lib/new_relic/agent/worker_loop.rb, line 43
def run(period = nil, &block)
  setup(period, block)
  while keep_running?
    sleep_time = schedule_next_invocation
    sleep(sleep_time) if sleep_time > 0
    run_task if keep_running?
    @iterations += 1
  end
end
run_task() click to toggle source

Executes the block given to the worker loop, and handles errors.

# File lib/new_relic/agent/worker_loop.rb, line 80
def run_task
  if @propagate_errors
    @task.call
  else
    begin
      @task.call
    rescue NewRelic::Agent::ForceRestartException, NewRelic::Agent::ForceDisconnectException
      # blow out the loop
      raise
    rescue => e
      # Don't blow out the stack for anything that hasn't already propagated
      ::NewRelic::Agent.logger.error('Error running task in agent worker loop:', e)
    end
  end
end
schedule_next_invocation() click to toggle source
# File lib/new_relic/agent/worker_loop.rb, line 53
def schedule_next_invocation
  now = Process.clock_gettime(Process::CLOCK_REALTIME)
  while @next_invocation_time <= now && @period > 0
    @next_invocation_time += @period
  end
  @next_invocation_time - Process.clock_gettime(Process::CLOCK_REALTIME)
end
setup(period, task) click to toggle source

Reset state that is changed by running the worker loop

# File lib/new_relic/agent/worker_loop.rb, line 29
def setup(period, task)
  @task = task
  @period = period if period
  @should_run = true
  @iterations = 0

  now = Process.clock_gettime(Process::CLOCK_REALTIME)
  @deadline = now + @duration if @duration
  @next_invocation_time = (now + @period)
end
stop() click to toggle source

Sets @should_run to false. Returns false

# File lib/new_relic/agent/worker_loop.rb, line 75
def stop
  @should_run = false
end
under_duration?() click to toggle source
# File lib/new_relic/agent/worker_loop.rb, line 66
def under_duration?
  !@deadline || Process.clock_gettime(Process::CLOCK_REALTIME) < @deadline
end
under_limit?() click to toggle source
# File lib/new_relic/agent/worker_loop.rb, line 70
def under_limit?
  @limit.nil? || @iterations < @limit
end