class Dynflow::Clock

Constants

Pills
Tick
Timer

Public Class Methods

new() click to toggle source
# File lib/dynflow/clock.rb, line 51
def initialize
  @timers        = SortedSet.new
  @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 74
def add_timer(timer)
  @timers.add 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 59
def default_reference_class
  ClockReference
end
on_event(event) click to toggle source
# File lib/dynflow/clock.rb, line 63
def on_event(event)
  if event == :terminated
    @sleeper.kill
  end
end
tick() click to toggle source
# File lib/dynflow/clock.rb, line 69
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 92
def first_timer
  @timers.first
end
run_ready_timers() click to toggle source
# File lib/dynflow/clock.rb, line 85
def run_ready_timers
  while first_timer && first_timer.when <= Time.now
    first_timer.apply
    @timers.delete(first_timer)
  end
end
sleep_to(timer) click to toggle source
# File lib/dynflow/clock.rb, line 105
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 114
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 96
def wakeup
  while @sleep_barrier.synchronize { Pill === @sleeping_pill }
    Thread.pass
  end
  @sleep_barrier.synchronize do
    @sleeper.wakeup if Took === @sleeping_pill
  end
end