monotime 0.7.1 → 0.8.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
-
[![Gem Version](https://badge.fury.io/rb/monotime.svg)](https://badge.fury.io/rb/monotime)
|
2
|
-
![Build Status](https://github.com/Freaky/monotime/actions/workflows/ci.yml/badge.svg)
|
3
|
-
[![Inline docs](http://inch-ci.org/github/Freaky/monotime.svg?branch=master)](http://inch-ci.org/github/Freaky/monotime)
|
4
|
-
[![Yard Docs](http://img.shields.io/badge/yard-docs-blue.svg)](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
|
+
[![Gem Version](https://badge.fury.io/rb/monotime.svg)](https://badge.fury.io/rb/monotime)
|
7
|
+
[![Build Status](https://github.com/Freaky/monotime/actions/workflows/ci.yml/badge.svg)](https://github.com/Freaky/monotime/actions)
|
8
|
+
[![Inline docs](http://inch-ci.org/github/Freaky/monotime.svg?branch=master)](http://inch-ci.org/github/Freaky/monotime)
|
9
|
+
[![Yard Docs](http://img.shields.io/badge/yard-docs-blue.svg)](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
|