Class: Librato::Rack::Worker

Inherits:
Object
  • Object
show all
Defined in:
lib/librato/rack/worker.rb

Overview

Runs a given piece of code periodically, ensuring that it will be run again at the proper interval regardless of how long execution takes.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options = {}) ⇒ Worker

available options:

* timer - type of timer to use, valid options are
          :sleep (default), :eventmachine, or :synchrony
* sync  - try to synchronize timer executions to whole
          minutes or subdivisions thereof


15
16
17
18
19
# File 'lib/librato/rack/worker.rb', line 15

def initialize(options={})
  @interrupt = false
  @timer = (options[:timer] || :sleep).to_sym
  @sync = options[:sync] || false
end

Instance Attribute Details

#timerObject (readonly)

Returns the value of attribute timer.



8
9
10
# File 'lib/librato/rack/worker.rb', line 8

def timer
  @timer
end

Instance Method Details

#run_periodically(period, &block) ⇒ Object

run the given block every <period> seconds, looping infinitely unless @interrupt becomes true.



24
25
26
27
28
29
30
31
32
# File 'lib/librato/rack/worker.rb', line 24

def run_periodically(period, &block)
  @proc = block # store

  if [:eventmachine, :synchrony].include?(timer)
    compensated_repeat(period) # threading is already handled
  else
    @thread = Thread.new { compensated_repeat(period) }
  end
end

#start_time(period) ⇒ Object

Give some structure to worker start times so when possible they will be in sync.



37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/librato/rack/worker.rb', line 37

def start_time(period)
  if @sync
    earliest = Time.now + period
    # already on a whole minute
    return earliest if earliest.sec == 0
    if period > 30
      # bump to whole minute
      earliest + (60-earliest.sec)
    else
      # ensure sync to whole minute if minute is evenly divisible
      earliest + (period-(earliest.sec%period))
    end
  else
    if period > 30
      # ensure some wobble in start times,
      # trade a slightly irregular first period for a more even
      # distribution for network requests between processes
      start = Time.now
      start + (60-start.sec) + rand(60)
    else
      Time.now + period
    end
  end
end

#stop!Object

stop worker loop at the beginning of the next round of execution



64
65
66
# File 'lib/librato/rack/worker.rb', line 64

def stop!
  @interrupt = true
end