class Dynflow::Clock

Constants

Pills
Tick
Timer

Public Class Methods

new(logger = nil) click to toggle source
# File lib/dynflow/clock.rb, line 49
def initialize(logger = nil)
  @logger        = logger
  @timers        = Utils::PriorityQueue.new { |a, b| b <=> a }
  @sleeping_pill = None
  @sleep_barrier = Mutex.new
  @sleeper       = Thread.new { sleeping }
  Thread.pass until @sleep_barrier.locked? || @sleeper.status == 'sleep'
end

Public Instance Methods

add_timer(timer) click to toggle source
# File lib/dynflow/clock.rb, line 73
def add_timer(timer)
  @timers.push timer
  if @timers.size == 1
    sleep_to timer
  else
    wakeup if timer == first_timer
  end
end
default_reference_class() click to toggle source
# File lib/dynflow/clock.rb, line 58
def default_reference_class
  ClockReference
end
on_event(event) click to toggle source
# File lib/dynflow/clock.rb, line 62
def on_event(event)
  if event == :terminated
    @sleeper.kill
  end
end
tick() click to toggle source
# File lib/dynflow/clock.rb, line 68
def tick
  run_ready_timers
  sleep_to first_timer
end

Private Instance Methods

first_timer() click to toggle source
# File lib/dynflow/clock.rb, line 95
def first_timer
  @timers.top
end
run_ready_timers() click to toggle source
# File lib/dynflow/clock.rb, line 84
def run_ready_timers
  while first_timer && first_timer.when <= Time.now
    begin
      first_timer.apply
    rescue => e
      @logger && @logger.error("Failed to apply clock event #{first_timer}, exception: #{e}")
    end
    @timers.pop
  end
end
sleep_to(timer) click to toggle source
# File lib/dynflow/clock.rb, line 108
def sleep_to(timer)
  return unless timer
  sec = [timer.when - Time.now, 0.0].max
  @sleep_barrier.synchronize do
    @sleeping_pill = Pill[sec]
    @sleeper.wakeup
  end
end
sleeping() click to toggle source
# File lib/dynflow/clock.rb, line 117
def sleeping
  @sleep_barrier.synchronize do
    loop do
      @sleeping_pill = None
      @sleep_barrier.sleep
      pill           = @sleeping_pill
      @sleeping_pill = Took
      @sleep_barrier.sleep pill.value
      reference.tell(:tick)
    end
  end
end
wakeup() click to toggle source
# File lib/dynflow/clock.rb, line 99
def wakeup
  while @sleep_barrier.synchronize { Pill === @sleeping_pill }
    Thread.pass
  end
  @sleep_barrier.synchronize do
    @sleeper.wakeup if Took === @sleeping_pill
  end
end