Class: NewRelic::Agent::WorkerLoop
- Inherits:
-
Object
- Object
- NewRelic::Agent::WorkerLoop
- 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.
Instance Method Summary collapse
-
#initialize(opts = {}) ⇒ WorkerLoop
constructor
Optional argument :duration (in seconds) for how long the worker loop runs or :limit (integer) for max number of iterations.
-
#keep_running? ⇒ Boolean
a simple accessor for @should_run.
-
#lock ⇒ Object
returns a class-level memoized mutex to make sure we don’t run overlapping.
-
#log ⇒ Object
a helper to access the NewRelic::Control.instance.log.
-
#run(period = nil, &block) ⇒ Object
Run infinitely, calling the registered tasks at their specified call periods.
-
#run_task ⇒ Object
Executes the block given to the worker loop, and handles many possible errors.
-
#stop ⇒ Object
Sets @should_run to false.
- #under_duration? ⇒ Boolean
- #under_limit? ⇒ Boolean
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
11 12 13 14 15 16 17 18 19 |
# File 'lib/new_relic/agent/worker_loop.rb', line 11 def initialize(opts={}) @log = log @should_run = true @next_invocation_time = Time.now @period = 60.0 @deadline = Time.now + opts[:duration] if opts[:duration] @limit = opts[:limit] if opts[:limit] @iterations = 0 end |
Instance Method Details
#keep_running? ⇒ Boolean
a simple accessor for @should_run
51 52 53 54 |
# File 'lib/new_relic/agent/worker_loop.rb', line 51 def keep_running? @now = Time.now @should_run && under_duration? && under_limit? end |
#lock ⇒ Object
returns a class-level memoized mutex to make sure we don’t run overlapping
22 23 24 |
# File 'lib/new_relic/agent/worker_loop.rb', line 22 def lock @@lock ||= Mutex.new end |
#log ⇒ Object
a helper to access the NewRelic::Control.instance.log
27 28 29 |
# File 'lib/new_relic/agent/worker_loop.rb', line 27 def log NewRelic::Control.instance.log 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.
34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
# File 'lib/new_relic/agent/worker_loop.rb', line 34 def run(period=nil, &block) @period = period if period @next_invocation_time = (Time.now + @period) @task = block while keep_running? do while @now < @next_invocation_time # sleep until this next task's scheduled invocation time sleep_time = @next_invocation_time - @now sleep sleep_time if sleep_time > 0 @now = Time.now end run_task if keep_running? @iterations += 1 if !@limit.nil? end end |
#run_task ⇒ Object
Executes the block given to the worker loop, and handles many possible errors. Also updates the execution time so that the next run occurs on schedule, even if we execute at some odd time
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 |
# File 'lib/new_relic/agent/worker_loop.rb', line 72 def run_task begin lock.synchronize do @task.call end rescue ServerError => e log.debug "Server Error: #{e}" rescue NewRelic::Agent::ForceRestartException, NewRelic::Agent::ForceDisconnectException # blow out the loop raise rescue RuntimeError => e # This is probably a server error which has been logged in the server along # with your account name. log.error "Error running task in worker loop, likely a server error (#{e})" log.debug e.backtrace.join("\n") rescue Timeout::Error, NewRelic::Agent::ServerConnectionException # Want to ignore these because they are handled already rescue SystemExit, NoMemoryError, SignalException raise rescue => e # Don't blow out the stack for anything that hasn't already propagated log.error "Error running task in Agent Worker Loop '#{e}': #{e.backtrace.first}" log.debug e.backtrace.join("\n") end now = Time.now while @next_invocation_time <= now && @period > 0 @next_invocation_time += @period end end |
#stop ⇒ Object
Sets @should_run to false. Returns false
65 66 67 |
# File 'lib/new_relic/agent/worker_loop.rb', line 65 def stop @should_run = false end |
#under_duration? ⇒ Boolean
56 57 58 |
# File 'lib/new_relic/agent/worker_loop.rb', line 56 def under_duration? !@deadline || @now < @deadline end |
#under_limit? ⇒ Boolean
60 61 62 |
# File 'lib/new_relic/agent/worker_loop.rb', line 60 def under_limit? !@limit || @iterations < @limit end |