Timers using the system clock are inherently buggy. This PR copies the monotonic clock from concurrent-ruby into this gem and uses it for the timers in TimedStack. This optimization in concurrent-ruby was originally suggested by Aaron Patterson.
The system clock is bad for timers because it regularly changes: NTP synchronization, VM adjustment, manual change, etc. Monotonic clocks exist specifically for timers and are generally controlled directly by the processor. Modern operating systems all have a monotonic clock, but older versions of Ruby do not provide access to it.
The clock class in this PR detects the availability of a monotonic clock. On Ruby versions where a monotonic clock is available (MRI 2.1 and newer, all JRuby) it is used. One other systems (MRI 2.0.0 and earlier, Rubinius) a pure-Ruby monotonic clock is used. This application-level clock follows the most common algorithm.
In all cases this clock is at least as accurate as the existing method (using the system clock). In many cases this clock is more accurate.
NOTE: I chose to copy the clock from c-r rather than add a runtime dependency. This gem is very elegant, lightweight, and currently has no runtime dependencies. Adding all of c-r just for the clock felt inappropriate.
Timers using the system clock are inherently buggy. This PR copies the monotonic clock from concurrent-ruby into this gem and uses it for the timers in
TimedStack
. This optimization in concurrent-ruby was originally suggested by Aaron Patterson.The system clock is bad for timers because it regularly changes: NTP synchronization, VM adjustment, manual change, etc. Monotonic clocks exist specifically for timers and are generally controlled directly by the processor. Modern operating systems all have a monotonic clock, but older versions of Ruby do not provide access to it.
The clock class in this PR detects the availability of a monotonic clock. On Ruby versions where a monotonic clock is available (MRI 2.1 and newer, all JRuby) it is used. One other systems (MRI 2.0.0 and earlier, Rubinius) a pure-Ruby monotonic clock is used. This application-level clock follows the most common algorithm.
In all cases this clock is at least as accurate as the existing method (using the system clock). In many cases this clock is more accurate.
NOTE: I chose to copy the clock from c-r rather than add a runtime dependency. This gem is very elegant, lightweight, and currently has no runtime dependencies. Adding all of c-r just for the clock felt inappropriate.