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.
-
#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 |
# File 'lib/new_relic/agent/worker_loop.rb', line 11 def initialize(opts={}) @should_run = true @next_invocation_time = Time.now @period = 60.0 @duration = 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
46 47 48 49 |
# File 'lib/new_relic/agent/worker_loop.rb', line 46 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
21 22 23 |
# File 'lib/new_relic/agent/worker_loop.rb', line 21 def lock @@lock ||= Mutex.new 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.
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
# File 'lib/new_relic/agent/worker_loop.rb', line 28 def run(period=nil, &block) @deadline = Time.now + @duration if @duration @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
67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 |
# File 'lib/new_relic/agent/worker_loop.rb', line 67 def run_task begin lock.synchronize do @task.call end rescue ServerError => e ::NewRelic::Agent.logger.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. ::NewRelic::Agent.logger.error "Error running task in worker loop, likely a server error:", e 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 ::NewRelic::Agent.logger.error "Error running task in Agent Worker Loop:", e 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
60 61 62 |
# File 'lib/new_relic/agent/worker_loop.rb', line 60 def stop @should_run = false end |
#under_duration? ⇒ Boolean
51 52 53 |
# File 'lib/new_relic/agent/worker_loop.rb', line 51 def under_duration? !@deadline || @now < @deadline end |
#under_limit? ⇒ Boolean
55 56 57 |
# File 'lib/new_relic/agent/worker_loop.rb', line 55 def under_limit? !@limit || @iterations < @limit end |