Class: Monotime::Instant
- Inherits:
-
Object
- Object
- Monotime::Instant
- Includes:
- Comparable
- Defined in:
- lib/monotime/instant.rb
Overview
A measurement from the operating system’s monotonic clock, with up to nanosecond precision.
Class Attribute Summary collapse
- .clock_id ⇒ Object
-
.monotonic_function(function) ⇒ Object
The function used to create
Instant
instances.
Class Method Summary collapse
-
.clock_getres(clock = clock_id) ⇒ Object
Return the claimed resolution of the given clock id or the configured
clock_id
, as aDuration
, ornil
if invalid. -
.clock_name ⇒ Symbol?
The symbolic name of the currently-selected
clock_id
, if available. -
.now ⇒ Instant
An alias to
new
, and generally preferred over it.
Instance Method Summary collapse
-
#+(other) ⇒ Instant
Add a
Duration
or#to_nanos
-coercible object to thisInstant
, returning a newInstant
. -
#-(other) ⇒ Duration, Instant
Subtract another
Instant
to generate aDuration
between the two, or aDuration
or#to_nanos
-coercible object, to generate anInstant
offset by it. -
#<=>(other) ⇒ -1, ...
Determine if the given
Instant
is before, equal to or after this one. -
#==(other) ⇒ Boolean
(also: #eql?)
Determine if
other
‘s value equals that of thisInstant
. -
#duration_since(earlier) ⇒ Duration
Return a
Duration
between thisInstant
and another. -
#elapsed ⇒ Duration
Return a
Duration
since thisInstant
and now. -
#hash ⇒ Integer
Generate a hash for this type and value.
-
#in_future? ⇒ Boolean
(also: #future?)
Return whether this
Instant
is in the future. -
#in_past? ⇒ Boolean
(also: #past?)
Return whether this
Instant
is in the past. -
#initialize(nanos = self.class.monotonic_function.call) ⇒ Instant
constructor
Create a new
Instant
from an optional nanosecond measurement. -
#sleep(duration = nil) ⇒ Duration
Sleep until this
Instant
, plus an optionalDuration
, returning aDuration
that’s either positive if any time was slept, or negative if sleeping would require time travel. -
#sleep_millis(millis) ⇒ Duration
Sleep for the given number of milliseconds past this
Instant
, if any. -
#sleep_secs(secs) ⇒ Duration
Sleep for the given number of seconds past this
Instant
, if any. -
#to_s ⇒ Object
Sugar for
#elapsed.to_s
.
Constructor Details
#initialize(nanos = self.class.monotonic_function.call) ⇒ Instant
Create a new Instant
from an optional nanosecond measurement.
Users should generally not pass anything to this function.
127 128 129 130 |
# File 'lib/monotime/instant.rb', line 127 def initialize(nanos = self.class.monotonic_function.call) @ns = Integer(nanos) freeze end |
Class Attribute Details
.clock_id ⇒ Numeric .clock_id=(id) ⇒ Object
52 53 54 |
# File 'lib/monotime/instant.rb', line 52 def clock_id @clock_id end |
.monotonic_function=(function) ⇒ Object
The function used to create Instant
instances.
This function must return a Numeric
, monotonic count of nanoseconds since a fixed point in the past.
Defaults to -> { Process.clock_gettime(clock_id, :nanosecond) }.
63 64 65 |
# File 'lib/monotime/instant.rb', line 63 def monotonic_function @monotonic_function end |
Class Method Details
.clock_getres(clock = clock_id) ⇒ Object
Return the claimed resolution of the given clock id or the configured clock_id
, as a Duration
, or nil
if invalid.
Note per Ruby issue #16740, the practical usability of this method is dubious and non-portable.
72 73 74 75 76 |
# File 'lib/monotime/instant.rb', line 72 def clock_getres(clock = clock_id) Duration.from_nanos(Integer(Process.clock_getres(clock, :nanosecond))) rescue SystemCallError # suppress errors end |
.clock_name ⇒ Symbol?
The symbolic name of the currently-selected clock_id
, if available.
81 82 83 84 85 86 87 |
# File 'lib/monotime/instant.rb', line 81 def clock_name return clock_id if clock_id.is_a? Symbol Process.constants.find do |c| c.to_s.start_with?('CLOCK_') && Process.const_get(c) == clock_id end end |
.now ⇒ Instant
An alias to new
, and generally preferred over it.
135 136 137 |
# File 'lib/monotime/instant.rb', line 135 def self.now new end |
Instance Method Details
#+(other) ⇒ Instant
Add a Duration
or #to_nanos
-coercible object to this Instant
, returning a new Instant
.
242 243 244 245 246 |
# File 'lib/monotime/instant.rb', line 242 def +(other) raise TypeError, 'Not one of: [Duration, #to_nanos]' unless other.respond_to?(:to_nanos) Instant.new(@ns + other.to_nanos) end |
#-(other) ⇒ Duration, Instant
Subtract another Instant
to generate a Duration
between the two, or a Duration
or #to_nanos
-coercible object, to generate an Instant
offset by it.
258 259 260 261 262 263 264 265 266 267 268 |
# File 'lib/monotime/instant.rb', line 258 def -(other) if other.is_a?(Instant) # @type var other: Instant Duration.new(@ns - other.ns) elsif other.respond_to?(:to_nanos) # @type var other: Duration | _ToNanos Instant.new(@ns - other.to_nanos) else raise TypeError, 'Not one of: [Instant, Duration, #to_nanos]' end end |
#<=>(other) ⇒ -1, ...
Determine if the given Instant
is before, equal to or after this one. nil
if not passed an Instant
.
274 275 276 |
# File 'lib/monotime/instant.rb', line 274 def <=>(other) @ns <=> other.ns if other.is_a?(Instant) end |
#==(other) ⇒ Boolean Also known as: eql?
Determine if other
‘s value equals that of this Instant
. Use eql?
if type checks are desired for future compatibility.
283 284 285 |
# File 'lib/monotime/instant.rb', line 283 def ==(other) other.is_a?(Instant) && @ns == other.ns end |
#duration_since(earlier) ⇒ Duration
Return a Duration
between this Instant
and another.
143 144 145 146 147 148 149 150 151 |
# File 'lib/monotime/instant.rb', line 143 def duration_since(earlier) raise TypeError, 'Not an Instant' unless earlier.is_a?(Instant) # `earlier - self` is cleaner, but upsets type checks and duplicates our # type checks. # @type var earlier: Instant Duration.new(earlier.ns - @ns) end |
#elapsed ⇒ Duration
Return a Duration
since this Instant
and now.
156 157 158 |
# File 'lib/monotime/instant.rb', line 156 def elapsed duration_since(self.class.now) end |
#hash ⇒ Integer
Generate a hash for this type and value.
292 293 294 |
# File 'lib/monotime/instant.rb', line 292 def hash [self.class, @ns].hash end |
#in_future? ⇒ Boolean Also known as: future?
Return whether this Instant
is in the future.
172 173 174 |
# File 'lib/monotime/instant.rb', line 172 def in_future? elapsed.negative? end |
#in_past? ⇒ Boolean Also known as: past?
Return whether this Instant
is in the past.
163 164 165 |
# File 'lib/monotime/instant.rb', line 163 def in_past? elapsed.positive? end |
#sleep(duration = nil) ⇒ Duration
Sleep until this Instant
, plus an optional Duration
, returning a Duration
that’s either positive if any time was slept, or negative if sleeping would require time travel.
195 196 197 198 199 200 201 202 203 |
# File 'lib/monotime/instant.rb', line 195 def sleep(duration = nil) remaining = if duration Duration.from_nanos(duration.to_nanos - elapsed.to_nanos) else -elapsed end remaining.tap { |rem| rem.sleep if rem.positive? } end |
#sleep_millis(millis) ⇒ Duration
Sleep for the given number of milliseconds past this Instant
, if any.
Equivalent to #sleep(Duration.from_millis(millis))
223 224 225 |
# File 'lib/monotime/instant.rb', line 223 def sleep_millis(millis) sleep(Duration.from_millis(millis)) end |
#sleep_secs(secs) ⇒ Duration
Sleep for the given number of seconds past this Instant
, if any.
Equivalent to #sleep(Duration.from_secs(secs))
212 213 214 |
# File 'lib/monotime/instant.rb', line 212 def sleep_secs(secs) sleep(Duration.from_secs(secs)) end |
#to_s ⇒ Object
Sugar for #elapsed.to_s
.
230 231 232 |
# File 'lib/monotime/instant.rb', line 230 def to_s(...) elapsed.to_s(...) end |