monotime 0.7.1 → 0.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/ci.yml +4 -3
- data/.rubocop.yml +7 -1
- data/CHANGELOG.md +129 -51
- data/README.md +17 -11
- data/lib/monotime/duration.rb +59 -12
- data/lib/monotime/instant.rb +65 -4
- data/lib/monotime/version.rb +2 -2
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 207159be0c76004c8676ac860106cd133344a29ca0021decbc14bc7448a17fab
|
4
|
+
data.tar.gz: 89c97583a40bfe82dd7c822cfd9a165be19c796cdf32396ee49ef861bbf7fb32
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c3aa917f832adedaa98acca61c58858d9e4ce57922d3ba457921b2e2c8adc023875a328c308258555f38dbb482168da73f7488c6306bd9751089b3ef21f5e7b0
|
7
|
+
data.tar.gz: b340008fa59637177c6c3caad1d4f5816ba8626a533993d3cc8de615b4c12899b3939e4338f6dae04d66fa09c90e6d7de06667cd02af915c2717bef7fca9aa25
|
data/.github/workflows/ci.yml
CHANGED
@@ -2,13 +2,14 @@ name: CI
|
|
2
2
|
on: [push, pull_request]
|
3
3
|
jobs:
|
4
4
|
test:
|
5
|
-
runs-on: ubuntu-latest
|
6
5
|
strategy:
|
7
6
|
fail-fast: false
|
8
7
|
matrix:
|
9
|
-
|
8
|
+
os: [ubuntu-latest, macos-latest]
|
9
|
+
ruby: ['2.7', '3.0', '3.1', '3.2', head, jruby, jruby-head, truffleruby, truffleruby-head]
|
10
|
+
runs-on: ${{ matrix.os }}
|
10
11
|
steps:
|
11
|
-
- uses: actions/checkout@
|
12
|
+
- uses: actions/checkout@v4
|
12
13
|
- uses: ruby/setup-ruby@v1
|
13
14
|
with:
|
14
15
|
ruby-version: ${{ matrix.ruby }}
|
data/.rubocop.yml
CHANGED
@@ -11,7 +11,10 @@ Layout/LineLength:
|
|
11
11
|
Max: 96
|
12
12
|
|
13
13
|
Metrics/ClassLength:
|
14
|
-
Max:
|
14
|
+
Max: 140
|
15
|
+
|
16
|
+
Metrics/MethodLength:
|
17
|
+
Max: 20
|
15
18
|
|
16
19
|
Style/AsciiComments:
|
17
20
|
Enabled: false
|
@@ -36,3 +39,6 @@ Style/ExplicitBlockArgument:
|
|
36
39
|
|
37
40
|
Style/MixinUsage:
|
38
41
|
Enabled: false
|
42
|
+
|
43
|
+
Style/TrailingCommaInArrayLiteral:
|
44
|
+
Enabled: false
|
data/CHANGELOG.md
CHANGED
@@ -1,100 +1,172 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
-
## 0.
|
3
|
+
## [0.8.1] - 2023-09-18
|
4
|
+
|
5
|
+
### Changed
|
6
|
+
|
7
|
+
- After further consideration, return to defaulting to `CLOCK_MONOTONIC` instead
|
8
|
+
of the overly-elaborate auto-selection introduced in 0.8.0.
|
9
|
+
|
10
|
+
### Removed
|
11
|
+
|
12
|
+
- `Instant.clock_name`. No I'm not incrementing to 0.9. It's been a few hours,
|
13
|
+
you're not using it, shut up.
|
14
|
+
|
15
|
+
## [0.8.0] - 2023-09-17
|
16
|
+
|
4
17
|
### Added
|
5
|
-
|
6
|
-
|
18
|
+
|
19
|
+
- Default precision for `Duration#to_s` can be set using
|
20
|
+
`Duration.default_to_s_precision=`.
|
21
|
+
- Default sleep function can be set using `Duration.sleep_function=`
|
22
|
+
- `Duration::ZERO` and `Duration.zero` for an easy, memory-efficient
|
23
|
+
zero-duration singleton.
|
24
|
+
- `Instant.clock_id` and `Instant.clock_id=` to control the default clock
|
25
|
+
source.
|
26
|
+
- `Instant.clock_getres` to get the minimum supported `Duration` from the
|
27
|
+
selected clock source.
|
28
|
+
- `Instant.monotonic_function=` to completely replace the default monotonic
|
29
|
+
function.
|
7
30
|
|
8
31
|
### Changed
|
9
|
-
|
10
|
-
|
11
|
-
|
32
|
+
|
33
|
+
- The default clock source is now chosen from a selection of options instead of
|
34
|
+
defaulting to `CLOCK_MONOTONIC``. Where possible options are used which are
|
35
|
+
unaffected by NTP frequency skew and which do not count time in system suspend.
|
36
|
+
- CI matrix drops Ruby 2.5 and 2.6 and adds 3.1, 3.2, head branches of Ruby,
|
37
|
+
JRuby, and TruffleRuby, and also tests under macOS.
|
38
|
+
|
39
|
+
### Fixed
|
40
|
+
|
41
|
+
- CI on TruffleRuby has been fixed by disabling SimpleCov.
|
42
|
+
- Several fragile tests depending on relatively narrow sleep times have been fixed.
|
43
|
+
|
44
|
+
### Thanks
|
45
|
+
|
46
|
+
- [@petergoldstein] for fixing CI on TruffleRuby and adding 3.1 and 3.2.
|
47
|
+
- [@fig] for fixing a README error.
|
48
|
+
|
49
|
+
## [0.7.1] - 2021-10-22
|
50
|
+
|
51
|
+
### Added
|
52
|
+
|
53
|
+
- `simplecov` introduced to test suite.
|
54
|
+
- `monotime/include.rb` to auto-include types globally.
|
55
|
+
|
56
|
+
### Changed
|
57
|
+
|
58
|
+
- All `Instant` and `Duration` instances are now frozen.
|
59
|
+
- Migrate from Travis CI to Github Actions
|
60
|
+
- Update development dependency on `rake`.
|
12
61
|
|
13
62
|
## [0.7.0] - 2019-04-24
|
63
|
+
|
14
64
|
### Added
|
15
|
-
|
16
|
-
|
65
|
+
|
66
|
+
- `Duration.with_measure`, which yields and returns an array containing its
|
67
|
+
evaluated return value and its `Duration`.
|
17
68
|
|
18
69
|
### Changed
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
70
|
+
|
71
|
+
- Break `Duration` and `Instant` into their own files.
|
72
|
+
- Rename `Monotime::VERSION` to `Monotime::MONOTIME_VERSION` to reduce
|
73
|
+
potential for collision if the module is included.
|
74
|
+
- Update to bundler 2.0.
|
75
|
+
- Rework README.md. Includes fix for [issue #1] (added a "See Also" section).
|
24
76
|
|
25
77
|
## [0.6.1] - 2018-10-26
|
78
|
+
|
26
79
|
### Fixed
|
27
|
-
|
28
|
-
|
80
|
+
|
81
|
+
- Build gem from a clean git checkout, not my local development directory.
|
82
|
+
No functional changes.
|
29
83
|
|
30
84
|
## [0.6.0] - 2018-10-26
|
85
|
+
|
31
86
|
### Added
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
87
|
+
|
88
|
+
- This `CHANGELOG.md` by request of [@celsworth].
|
89
|
+
- Aliases for `Duration.from_*` and `Duration#to_*` without the prefix. e.g.
|
90
|
+
`Duration.from_secs(42).to_secs == 42` can now be written as
|
91
|
+
`Duration.secs(42).secs == 42`.
|
92
|
+
- `Duration#nonzero?`.
|
93
|
+
- `Instant#in_past?` and `Instant#in_future?`.
|
38
94
|
|
39
95
|
## [0.5.0] - 2018-10-13
|
96
|
+
|
40
97
|
### Added
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
98
|
+
|
99
|
+
- `Duration#abs` to make a `Duration` positive.
|
100
|
+
- `Duration#-@` to invert the sign of a `Duration`.
|
101
|
+
- `Duration#positive?`
|
102
|
+
- `Duration#negative?`
|
103
|
+
- `Duration#zero?`
|
46
104
|
|
47
105
|
### Changed
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
106
|
+
|
107
|
+
- `Instant#sleep` with no argument now sleeps until the `Instant`.
|
108
|
+
- `Duration.from_*` no longer coerce their argument to `Float`.
|
109
|
+
- `Duration#==` checks value via `#to_nanos`, not type.
|
110
|
+
- `Duration#eql?` checks value and type.
|
111
|
+
- `Duration#<=>` compares value via `#to_nanos`.
|
53
112
|
|
54
113
|
## [0.4.0] - 2018-10-09
|
114
|
+
|
55
115
|
### Added
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
116
|
+
|
117
|
+
- `Instant#sleep` - sleep to a given `Duration` past an `Instant`.
|
118
|
+
- `Instant#sleep_secs` and `Instant#sleep_millis` convenience methods.
|
119
|
+
- `Duration#sleep` - sleep for the `Duration`.
|
120
|
+
- `Duration#*` - multiply a `Duration` by a number.
|
121
|
+
- `Duration#/` - divide a `Duration` by a number.
|
61
122
|
|
62
123
|
### Changed
|
63
|
-
|
124
|
+
|
125
|
+
More `#to_nanos` `Duration` duck-typing.
|
64
126
|
|
65
127
|
## [0.3.0] - 2018-10-04
|
128
|
+
|
66
129
|
### Added
|
67
|
-
|
130
|
+
|
131
|
+
- `#to_nanos` is now used to duck-type `Duration` everywhere.
|
68
132
|
|
69
133
|
### Changed
|
70
|
-
|
134
|
+
|
135
|
+
- Make `<=>` return nil on invalid types, rather than raising a `TypeError`.
|
71
136
|
|
72
137
|
### Removed
|
73
|
-
|
138
|
+
|
139
|
+
- Dependency on `dry-equalizer`.
|
74
140
|
|
75
141
|
## [0.2.0] - 2018-10-03
|
142
|
+
|
76
143
|
### Added
|
77
|
-
|
78
|
-
|
144
|
+
|
145
|
+
- `Instant#to_s` as an alias for `#elapsed.to_s`
|
146
|
+
- `Duration#to_nanos`, with some limited duck-typing.
|
79
147
|
|
80
148
|
### Changed
|
81
|
-
|
82
|
-
|
83
|
-
|
149
|
+
|
150
|
+
- Switch to microseconds internally.
|
151
|
+
- `Duration#to_{secs,millis,micros}` now return a `Float`.
|
152
|
+
- `Instant#ns` is now `protected`.
|
84
153
|
|
85
154
|
### Fixed
|
86
|
-
|
87
|
-
|
88
|
-
|
155
|
+
|
156
|
+
- `Duration#to_s` zero-stripping with precision=0.
|
157
|
+
- `Instant#-` argument ordering with other `Instant`.
|
158
|
+
- `Duration#to_micros` returns microseconds, not picoseconds.
|
89
159
|
|
90
160
|
### Removed
|
91
|
-
|
92
|
-
|
161
|
+
|
162
|
+
- `Instant` and `Duration` maths methods no longer support passing an `Integer`
|
163
|
+
number of nanoseconds.
|
93
164
|
|
94
165
|
## [0.1.0] - 2018-10-02
|
166
|
+
|
95
167
|
### Added
|
96
|
-
- Initial release
|
97
168
|
|
169
|
+
- Initial release
|
98
170
|
|
99
171
|
[0.1.0]: https://github.com/Freaky/monotime/commits/v0.1.0
|
100
172
|
[0.2.0]: https://github.com/Freaky/monotime/commits/v0.2.0
|
@@ -104,5 +176,11 @@
|
|
104
176
|
[0.6.0]: https://github.com/Freaky/monotime/commits/v0.6.0
|
105
177
|
[0.6.1]: https://github.com/Freaky/monotime/commits/v0.6.1
|
106
178
|
[0.7.0]: https://github.com/Freaky/monotime/commits/v0.7.0
|
179
|
+
[0.7.1]: https://github.com/Freaky/monotime/commits/v0.7.0
|
180
|
+
[0.8.0]: https://github.com/Freaky/monotime/commits/v0.8.0
|
181
|
+
[0.8.1]: https://github.com/Freaky/monotime/commits/v0.8.1
|
107
182
|
[issue #1]: https://github.com/Freaky/monotime/issues/1
|
183
|
+
[Ruby #16740]: https://bugs.ruby-lang.org/issues/16740
|
108
184
|
[@celsworth]: https://github.com/celsworth
|
185
|
+
[@petergoldstein]: https://github.com/petergoldstein
|
186
|
+
[@fig]: https://github.com/fig
|
data/README.md
CHANGED
@@ -1,12 +1,13 @@
|
|
1
|
-
[](https://badge.fury.io/rb/monotime)
|
2
|
-

|
3
|
-
[](http://inch-ci.org/github/Freaky/monotime)
|
4
|
-
[](https://www.rubydoc.info/gems/monotime)
|
5
1
|
|
6
2
|
# Monotime
|
7
3
|
|
8
4
|
A sensible interface to Ruby's monotonic clock, inspired by Rust.
|
9
5
|
|
6
|
+
[](https://badge.fury.io/rb/monotime)
|
7
|
+
[](https://github.com/Freaky/monotime/actions)
|
8
|
+
[](http://inch-ci.org/github/Freaky/monotime)
|
9
|
+
[](https://www.rubydoc.info/gems/monotime)
|
10
|
+
|
10
11
|
## Installation
|
11
12
|
|
12
13
|
Add this line to your application's Gemfile:
|
@@ -23,7 +24,7 @@ Or install it yourself as:
|
|
23
24
|
|
24
25
|
$ gem install monotime
|
25
26
|
|
26
|
-
`Monotime` is tested on Ruby 2.
|
27
|
+
`Monotime` is tested on Ruby 2.7+, TruffleRuby, and JRuby.
|
27
28
|
|
28
29
|
## Usage
|
29
30
|
|
@@ -106,7 +107,7 @@ Duration.secs(1).sleep # => 1
|
|
106
107
|
|
107
108
|
So can `Instant`, taking a `Duration` and sleeping until the given `Duration`
|
108
109
|
past the time the `Instant` was created, if any. This can be useful for
|
109
|
-
maintaining a precise
|
110
|
+
maintaining a precise cadence between tasks:
|
110
111
|
|
111
112
|
```ruby
|
112
113
|
interval = Duration.secs(60)
|
@@ -159,7 +160,7 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
|
|
159
160
|
|
160
161
|
## Contributing
|
161
162
|
|
162
|
-
Bug reports and pull requests are welcome on GitHub at https://github.com/Freaky/monotime
|
163
|
+
Bug reports and pull requests are welcome on GitHub at <https://github.com/Freaky/monotime>.
|
163
164
|
|
164
165
|
## License
|
165
166
|
|
@@ -169,14 +170,19 @@ The gem is available as open source under the terms of the [MIT License](https:/
|
|
169
170
|
|
170
171
|
### Core Ruby
|
171
172
|
|
172
|
-
For a zero-dependency alternative, see
|
173
|
+
For a zero-dependency alternative upon which `monotime` is based, see
|
173
174
|
[`Process.clock_gettime`](https://ruby-doc.org/core-2.6.3/Process.html#method-c-clock_gettime).
|
174
|
-
|
175
|
-
|
175
|
+
|
176
|
+
`Process::CLOCK_MONOTONIC` is a safe default, but other options may offer better
|
177
|
+
behaviour in face of NTP frequency skew or suspend/resume and should be evaluated
|
178
|
+
carefully.
|
176
179
|
|
177
180
|
### Other Gems
|
178
181
|
|
179
182
|
[hitimes](https://rubygems.org/gems/hitimes) is a popular and mature alternative
|
180
183
|
which also includes a variety of features for gathering statistics about
|
181
|
-
measurements
|
184
|
+
measurements.
|
182
185
|
|
186
|
+
[concurrent-ruby](https://rubygems.org/gems/concurrent-ruby) includes
|
187
|
+
`Concurrent.monotonic_time`, which is at the time of writing a trivial proxy to
|
188
|
+
the aforementioned `Process::clock_gettime` with `Process::CLOCK_MONOTONIC`.
|
data/lib/monotime/duration.rb
CHANGED
@@ -8,16 +8,57 @@ module Monotime
|
|
8
8
|
# Create a new +Duration+ of a specified number of nanoseconds, zero by
|
9
9
|
# default.
|
10
10
|
#
|
11
|
-
# Users are strongly advised to use
|
11
|
+
# Users are strongly advised to use +Duration.from_nanos+ instead.
|
12
12
|
#
|
13
13
|
# @param nanos [Integer]
|
14
|
-
# @see
|
14
|
+
# @see from_nanos
|
15
15
|
def initialize(nanos = 0)
|
16
16
|
@ns = Integer(nanos)
|
17
17
|
freeze
|
18
18
|
end
|
19
19
|
|
20
|
+
# A static instance for zero durations
|
21
|
+
ZERO = allocate.tap { |d| d.__send__(:initialize, 0) }
|
22
|
+
|
23
|
+
class << self
|
24
|
+
# The sleep function used by all +Monotime+ sleep functions.
|
25
|
+
#
|
26
|
+
# This function must accept a positive +Float+ number of seconds and return
|
27
|
+
# the +Float+ time slept.
|
28
|
+
#
|
29
|
+
# Defaults to +Kernel.method(:sleep)+
|
30
|
+
#
|
31
|
+
# @overload sleep_function=(function)
|
32
|
+
# @param function [#call]
|
33
|
+
attr_accessor :sleep_function
|
34
|
+
|
35
|
+
# Precision for +Duration#to_s+ if not otherwise specified
|
36
|
+
#
|
37
|
+
# Defaults to 9.
|
38
|
+
#
|
39
|
+
# @overload default_to_s_precision=(precision)
|
40
|
+
# @param precision [Numeric]
|
41
|
+
attr_accessor :default_to_s_precision
|
42
|
+
end
|
43
|
+
|
44
|
+
self.sleep_function = Kernel.method(:sleep)
|
45
|
+
self.default_to_s_precision = 9
|
46
|
+
|
20
47
|
class << self
|
48
|
+
# @!visibility private
|
49
|
+
def new(nanos = 0)
|
50
|
+
return ZERO if nanos.zero?
|
51
|
+
|
52
|
+
super
|
53
|
+
end
|
54
|
+
|
55
|
+
# Return a zero +Duration+.
|
56
|
+
#
|
57
|
+
# @return [Duration]
|
58
|
+
def zero
|
59
|
+
ZERO
|
60
|
+
end
|
61
|
+
|
21
62
|
# Generate a new +Duration+ measuring the given number of seconds.
|
22
63
|
#
|
23
64
|
# @param secs [Numeric]
|
@@ -87,7 +128,7 @@ module Monotime
|
|
87
128
|
# @example
|
88
129
|
# (Duration.from_secs(10) + Duration.from_secs(5)).to_s # => "15s"
|
89
130
|
#
|
90
|
-
# @param [Duration, #to_nanos]
|
131
|
+
# @param other [Duration, #to_nanos]
|
91
132
|
# @return [Duration]
|
92
133
|
def +(other)
|
93
134
|
raise TypeError, 'Not one of: [Duration, #to_nanos]' unless other.respond_to?(:to_nanos)
|
@@ -101,7 +142,7 @@ module Monotime
|
|
101
142
|
# @example
|
102
143
|
# (Duration.from_secs(10) - Duration.from_secs(5)).to_s # => "5s"
|
103
144
|
#
|
104
|
-
# @param [Duration, #to_nanos]
|
145
|
+
# @param other [Duration, #to_nanos]
|
105
146
|
# @return [Duration]
|
106
147
|
def -(other)
|
107
148
|
raise TypeError, 'Not one of: [Duration, #to_nanos]' unless other.respond_to?(:to_nanos)
|
@@ -114,7 +155,7 @@ module Monotime
|
|
114
155
|
# @example
|
115
156
|
# (Duration.from_secs(10) / 2).to_s # => "5s"
|
116
157
|
#
|
117
|
-
# @param [Numeric]
|
158
|
+
# @param other [Numeric]
|
118
159
|
# @return [Duration]
|
119
160
|
def /(other)
|
120
161
|
Duration.new(to_nanos / other)
|
@@ -125,7 +166,7 @@ module Monotime
|
|
125
166
|
# @example
|
126
167
|
# (Duration.from_secs(10) * 2).to_s # => "20s"
|
127
168
|
#
|
128
|
-
# @param [Numeric]
|
169
|
+
# @param other [Numeric]
|
129
170
|
# @return [Duration]
|
130
171
|
def *(other)
|
131
172
|
Duration.new(to_nanos * other)
|
@@ -158,7 +199,7 @@ module Monotime
|
|
158
199
|
# Compare the *value* of this +Duration+ with another, or any +#to_nanos+-coercible
|
159
200
|
# object, or nil if not comparable.
|
160
201
|
#
|
161
|
-
# @param [Duration, #to_nanos, Object]
|
202
|
+
# @param other [Duration, #to_nanos, Object]
|
162
203
|
# @return [-1, 0, 1, nil]
|
163
204
|
def <=>(other)
|
164
205
|
to_nanos <=> other.to_nanos if other.respond_to?(:to_nanos)
|
@@ -167,7 +208,7 @@ module Monotime
|
|
167
208
|
# Compare the equality of the *value* of this +Duration+ with another, or
|
168
209
|
# any +#to_nanos+-coercible object, or nil if not comparable.
|
169
210
|
#
|
170
|
-
# @param [Duration, #to_nanos, Object]
|
211
|
+
# @param other [Duration, #to_nanos, Object]
|
171
212
|
# @return [Boolean]
|
172
213
|
def ==(other)
|
173
214
|
other.respond_to?(:to_nanos) && to_nanos == other.to_nanos
|
@@ -175,7 +216,7 @@ module Monotime
|
|
175
216
|
|
176
217
|
# Check equality of the value and type of this +Duration+ with another.
|
177
218
|
#
|
178
|
-
# @param [Duration, Object]
|
219
|
+
# @param other [Duration, Object]
|
179
220
|
# @return [Boolean]
|
180
221
|
def eql?(other)
|
181
222
|
other.is_a?(Duration) && to_nanos == other.to_nanos
|
@@ -185,7 +226,7 @@ module Monotime
|
|
185
226
|
#
|
186
227
|
# @return [Integer]
|
187
228
|
def hash
|
188
|
-
self.class
|
229
|
+
[self.class, to_nanos].hash
|
189
230
|
end
|
190
231
|
|
191
232
|
# Return this +Duration+ in seconds.
|
@@ -255,6 +296,8 @@ module Monotime
|
|
255
296
|
# Sleep for the duration of this +Duration+. Equivalent to
|
256
297
|
# +Kernel.sleep(duration.to_secs)+.
|
257
298
|
#
|
299
|
+
# The sleep function may be overridden globally using +Duration.sleep_function=+
|
300
|
+
#
|
258
301
|
# @example
|
259
302
|
# Duration.from_secs(1).sleep # => 1
|
260
303
|
# Duration.from_secs(-1).sleep # => raises NotImplementedError
|
@@ -262,10 +305,11 @@ module Monotime
|
|
262
305
|
# @raise [NotImplementedError] negative +Duration+ sleeps are not yet supported.
|
263
306
|
# @return [Integer]
|
264
307
|
# @see Instant#sleep
|
308
|
+
# @see sleep_function=
|
265
309
|
def sleep
|
266
310
|
raise NotImplementedError, 'time travel module missing' if negative?
|
267
311
|
|
268
|
-
|
312
|
+
self.class.sleep_function.call(to_secs)
|
269
313
|
end
|
270
314
|
|
271
315
|
DIVISORS = [
|
@@ -280,6 +324,8 @@ module Monotime
|
|
280
324
|
# Format this +Duration+ into a human-readable string, with a given number
|
281
325
|
# of decimal places.
|
282
326
|
#
|
327
|
+
# The default precision may be set globally using +Duration.default_to_s_precision=+
|
328
|
+
#
|
283
329
|
# The exact format is subject to change, users with specific requirements
|
284
330
|
# are encouraged to use their own formatting methods.
|
285
331
|
#
|
@@ -293,7 +339,8 @@ module Monotime
|
|
293
339
|
#
|
294
340
|
# @param precision [Integer] the maximum number of decimal places
|
295
341
|
# @return [String]
|
296
|
-
|
342
|
+
# @see default_to_s_precision=
|
343
|
+
def to_s(precision = self.class.default_to_s_precision)
|
297
344
|
precision = Integer(precision).abs
|
298
345
|
div, unit = DIVISORS.find { |d, _| to_nanos.abs >= d }
|
299
346
|
|
data/lib/monotime/instant.rb
CHANGED
@@ -11,13 +11,74 @@ module Monotime
|
|
11
11
|
|
12
12
|
include Comparable
|
13
13
|
|
14
|
+
class << self
|
15
|
+
# @overload clock_id
|
16
|
+
# The +Process.clock_gettime+ clock id used to create +Instant+ instances
|
17
|
+
# by the default monotonic function.
|
18
|
+
#
|
19
|
+
# @return [Numeric]
|
20
|
+
#
|
21
|
+
# @overload clock_id=(id)
|
22
|
+
#
|
23
|
+
# Override the default +Process.clock_gettime+ clock id. Some potential
|
24
|
+
# choices include but are not limited to:
|
25
|
+
#
|
26
|
+
# * +Process::CLOCK_MONOTONIC_RAW+
|
27
|
+
# * +Process::CLOCK_UPTIME_RAW+
|
28
|
+
# * +Process::CLOCK_UPTIME_PRECISE+
|
29
|
+
# * +Process::CLOCK_UPTIME_FAST+
|
30
|
+
# * +Process::CLOCK_UPTIME+
|
31
|
+
# * +Process::CLOCK_MONOTONIC_PRECISE+
|
32
|
+
# * +Process::CLOCK_MONOTONIC_FAST+
|
33
|
+
# * +Process::CLOCK_MONOTONIC+
|
34
|
+
#
|
35
|
+
# These are platform-dependant and may vary in resolution, performance,
|
36
|
+
# and behaviour from NTP frequency skew and system suspend/resume, and
|
37
|
+
# should be selected with care.
|
38
|
+
#
|
39
|
+
# It is possible to set non-monotonic clock sources here. You probably
|
40
|
+
# shouldn't.
|
41
|
+
#
|
42
|
+
# Defaults to +Process::CLOCK_MONOTONIC+.
|
43
|
+
#
|
44
|
+
# @param id [Numeric]
|
45
|
+
attr_accessor :clock_id
|
46
|
+
|
47
|
+
# The function used to create +Instant+ instances.
|
48
|
+
#
|
49
|
+
# This function must return a +Numeric+, monotonic count of nanoseconds
|
50
|
+
# since a fixed point in the past.
|
51
|
+
#
|
52
|
+
# Defaults to +-> { Process.clock_gettime(clock_id, :nanosecond) }+.
|
53
|
+
#
|
54
|
+
# @overload monotonic_function=(function)
|
55
|
+
# @param function [#call]
|
56
|
+
attr_accessor :monotonic_function
|
57
|
+
|
58
|
+
# Return the claimed resolution of the given clock id or the configured
|
59
|
+
# +clock_id+, as a +Duration+, or +nil+ if invalid.
|
60
|
+
#
|
61
|
+
# Note per Ruby issue #16740, the practical usability of this method is
|
62
|
+
# dubious and non-portable.
|
63
|
+
#
|
64
|
+
# @param clock [Numeric] Optional clock id instead of default.
|
65
|
+
def clock_getres(clock = clock_id)
|
66
|
+
Duration.from_nanos(Process.clock_getres(clock, :nanosecond))
|
67
|
+
rescue SystemCallError
|
68
|
+
# suppress errors
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
self.monotonic_function = -> { Process.clock_gettime(clock_id, :nanosecond) }
|
73
|
+
self.clock_id = Process::CLOCK_MONOTONIC
|
74
|
+
|
14
75
|
# Create a new +Instant+ from an optional nanosecond measurement.
|
15
76
|
#
|
16
77
|
# Users should generally *not* pass anything to this function.
|
17
78
|
#
|
18
79
|
# @param nanos [Integer]
|
19
80
|
# @see #now
|
20
|
-
def initialize(nanos =
|
81
|
+
def initialize(nanos = self.class.monotonic_function.call)
|
21
82
|
@ns = Integer(nanos)
|
22
83
|
freeze
|
23
84
|
end
|
@@ -112,8 +173,8 @@ module Monotime
|
|
112
173
|
# Sugar for +#elapsed.to_s+.
|
113
174
|
#
|
114
175
|
# @see Duration#to_s
|
115
|
-
def to_s(
|
116
|
-
elapsed.to_s(
|
176
|
+
def to_s(...)
|
177
|
+
elapsed.to_s(...)
|
117
178
|
end
|
118
179
|
|
119
180
|
# Add a +Duration+ or +#to_nanos+-coercible object to this +Instant+, returning
|
@@ -173,7 +234,7 @@ module Monotime
|
|
173
234
|
#
|
174
235
|
# @return [Integer]
|
175
236
|
def hash
|
176
|
-
self.class
|
237
|
+
[self.class, @ns].hash
|
177
238
|
end
|
178
239
|
end
|
179
240
|
end
|
data/lib/monotime/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: monotime
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.8.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Thomas Hurst
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2023-09-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -109,7 +109,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
109
109
|
- !ruby/object:Gem::Version
|
110
110
|
version: '0'
|
111
111
|
requirements: []
|
112
|
-
rubygems_version: 3.
|
112
|
+
rubygems_version: 3.4.18
|
113
113
|
signing_key:
|
114
114
|
specification_version: 4
|
115
115
|
summary: A sensible interface to the monotonic clock
|