Class: Yuuki::PeriodicCaller
- Defined in:
- lib/yuuki/periodic_caller.rb,
sig/yuuki/periodic_caller.rbs
Instance Attribute Summary collapse
-
#current_time ⇒ Float?
readonly
epoch seconds of the current iteration; nil before #run is called.
-
#first_run ⇒ Boolean
readonly
true until the first iteration of #run has finished.
Instance Method Summary collapse
-
#initialize(*instances, use_yoshinon: true) ⇒ PeriodicCaller
constructor
A new instance of PeriodicCaller.
- #on_error {|arg0| ... } ⇒ void
-
#run(gmtoff = Time.now.gmtoff, **args, &block) ⇒ void
loops forever; only returns by raising (when no on_error callback is set).
Methods inherited from Caller
#add, #alive?, #join, #methods, require_dir, #run_internal, #run_method_internal, #run_select
Constructor Details
#initialize(*instances, use_yoshinon: true) ⇒ PeriodicCaller
Returns a new instance of PeriodicCaller.
11 12 13 14 |
# File 'lib/yuuki/periodic_caller.rb', line 11 def initialize(*instances, use_yoshinon: true) super @first_run = true end |
Instance Attribute Details
#current_time ⇒ Float? (readonly)
epoch seconds of the current iteration; nil before #run is called
9 10 11 |
# File 'sig/yuuki/periodic_caller.rbs', line 9 def current_time @current_time end |
#first_run ⇒ Boolean (readonly)
true until the first iteration of #run has finished
6 7 8 |
# File 'sig/yuuki/periodic_caller.rbs', line 6 def first_run @first_run end |
Instance Method Details
#on_error {|arg0| ... } ⇒ void
This method returns an undefined value.
16 17 18 |
# File 'lib/yuuki/periodic_caller.rb', line 16 def on_error(&block) @on_error = block end |
#run(gmtoff = Time.now.gmtoff, **args, &block) ⇒ void
This method returns an undefined value.
loops forever; only returns by raising (when no on_error callback is set)
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
# File 'sig/yuuki/periodic_caller.rbs', line 16 def run(gmtoff = Time.now.gmtoff, **args, &block) last_time = nil loop do @current_time = Time.now.to_f begin selector = proc do |_method, | next true if @first_run && [:first_run] next false unless [:periodic] next false unless last_time # gmtoff shifts epoch seconds into local time so that intervals # align with local clock boundaries (e.g. 86400 fires at local midnight). # Fires when a multiple of the interval lies in (last_time, current_time]. c = @current_time + gmtoff l = last_time + gmtoff (l.div([:periodic]) + 1) * [:periodic] <= c end run_select(selector, **args, &block) rescue StandardError @on_error ? @on_error[$!] : raise end @first_run = false last_time = @current_time # wake at the next wall-clock second; the boundary check above makes # ticks drift-free, but intervals below 1 second cannot be honored sleep_duration = (@current_time + 1).floor - Time.now.to_f sleep(sleep_duration) if sleep_duration > 0 end end |