class Polyphony::Timer
Implements a common timer for running multiple timeouts
Public Class Methods
new(tag = nil, resolution:)
click to toggle source
# File lib/polyphony/core/timer.rb, line 6 def initialize(tag = nil, resolution:) @fiber = spin_loop(tag, interval: resolution) { update } @timeouts = {} end
Public Instance Methods
after(interval, &block)
click to toggle source
# File lib/polyphony/core/timer.rb, line 26 def after(interval, &block) spin do self.sleep interval block.() end end
cancel_after(interval, with_exception: Polyphony::Cancel) { || ... }
click to toggle source
# File lib/polyphony/core/timer.rb, line 48 def cancel_after(interval, with_exception: Polyphony::Cancel) fiber = Fiber.current @timeouts[fiber] = { interval: interval, target_stamp: now + interval, exception: with_exception } yield ensure @timeouts.delete(fiber) end
every(interval) { || ... }
click to toggle source
# File lib/polyphony/core/timer.rb, line 33 def every(interval) fiber = Fiber.current @timeouts[fiber] = { interval: interval, target_stamp: now + interval, recurring: true } while true Polyphony.backend_wait_event(true) yield end ensure @timeouts.delete(fiber) end
move_on_after(interval, with_value: nil) { || ... }
click to toggle source
# File lib/polyphony/core/timer.rb, line 60 def move_on_after(interval, with_value: nil) fiber = Fiber.current @timeouts[fiber] = { interval: interval, target_stamp: now + interval, exception: [Polyphony::MoveOn, with_value] } yield rescue Polyphony::MoveOn => e e.value ensure @timeouts.delete(fiber) end
reset()
click to toggle source
# File lib/polyphony/core/timer.rb, line 74 def reset record = @timeouts[Fiber.current] return unless record record[:target_stamp] = now + record[:interval] end
sleep(duration)
click to toggle source
# File lib/polyphony/core/timer.rb, line 15 def sleep(duration) fiber = Fiber.current @timeouts[fiber] = { interval: duration, target_stamp: now + duration } Polyphony.backend_wait_event(true) ensure @timeouts.delete(fiber) end
stop()
click to toggle source
# File lib/polyphony/core/timer.rb, line 11 def stop @fiber.stop end
Private Instance Methods
now()
click to toggle source
# File lib/polyphony/core/timer.rb, line 83 def now ::Process.clock_gettime(::Process::CLOCK_MONOTONIC) end
timeout_exception(record)
click to toggle source
# File lib/polyphony/core/timer.rb, line 87 def timeout_exception(record) case (exception = record[:exception]) when Array exception[0].new(exception[1]) when Class exception.new else RuntimeError.new(exception) end end
update()
click to toggle source
# File lib/polyphony/core/timer.rb, line 98 def update return if @timeouts.empty? @timeouts.each do |fiber, record| next if record[:target_stamp] > now value = record[:exception] ? timeout_exception(record) : record[:value] fiber.schedule value next unless record[:recurring] while record[:target_stamp] <= now record[:target_stamp] += record[:interval] end end end