Class: NewRelic::Agent::WorkerLoop

Inherits:
Object
  • Object
show all
Defined in:
lib/new_relic/agent/worker_loop.rb

Overview

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.

API:

  • public

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(opts = {}) ⇒ WorkerLoop

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

API:

  • public



17
18
19
20
21
22
23
24
25
26
# 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

Instance Attribute Details

#iterationsObject (readonly)

API:

  • public



13
14
15
# File 'lib/new_relic/agent/worker_loop.rb', line 13

def iterations
  @iterations
end

#periodObject

API:

  • public



12
13
14
# File 'lib/new_relic/agent/worker_loop.rb', line 12

def period
  @period
end

#propagate_errorsObject

API:

  • public



12
13
14
# File 'lib/new_relic/agent/worker_loop.rb', line 12

def propagate_errors
  @propagate_errors
end

Instance Method Details

#keep_running?Boolean

a simple accessor for @should_run

Returns:

API:

  • public



62
63
64
# File 'lib/new_relic/agent/worker_loop.rb', line 62

def keep_running?
  @should_run && under_duration? && under_limit?
end

#run(period = nil, &block) ⇒ Object

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.

API:

  • public



43
44
45
46
47
48
49
50
51
# 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_taskObject

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

API:

  • public



80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# 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_invocationObject

API:

  • public



53
54
55
56
57
58
59
# 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) ⇒ Object

Reset state that is changed by running the worker loop

API:

  • public



29
30
31
32
33
34
35
36
37
38
# 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

#stopObject

Sets @should_run to false. Returns false

API:

  • public



75
76
77
# File 'lib/new_relic/agent/worker_loop.rb', line 75

def stop
  @should_run = false
end

#under_duration?Boolean

Returns:

API:

  • public



66
67
68
# File 'lib/new_relic/agent/worker_loop.rb', line 66

def under_duration?
  !@deadline || Process.clock_gettime(Process::CLOCK_REALTIME) < @deadline
end

#under_limit?Boolean

Returns:

API:

  • public



70
71
72
# File 'lib/new_relic/agent/worker_loop.rb', line 70

def under_limit?
  @limit.nil? || @iterations < @limit
end