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