monotime 0.8.0 → 0.8.2
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/CHANGELOG.md +34 -2
- data/README.md +4 -4
- data/lib/monotime/duration.rb +3 -1
- data/lib/monotime/instant.rb +62 -55
- data/lib/monotime/version.rb +1 -1
- data/monotime.gemspec +2 -0
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fa145221981b5ff0adb6d1cd3aa77a7e9e9a32942ab9a849a2f83a0d434e245d
|
4
|
+
data.tar.gz: c86e6a4ca11e2e9569089574662e96d2cf0ef1b2216ee638832099a5570cd5da
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 78a3a8dc8817cc0f99b67d2839d341e01259815c1fefce78ad0d619f2a4c2739414896a98322a2dd620d105b3b1636f6d355d2250deb71920e3a444d970bc0c4
|
7
|
+
data.tar.gz: 5408bc28e13df38a04228eedd325371f7136c036c6ab57c0775c7adc401d4e516acae375502bf16d1f5e3945fe2aaf9b60e6e8549d57570a16d4ec59b10a5b99
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,34 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## [0.8.2] - 2023-09-22
|
4
|
+
|
5
|
+
### Added
|
6
|
+
|
7
|
+
- `Instant.clock_name` is back and now tracks `clock_id` using reflection.
|
8
|
+
- Explicit minimum Ruby version in gemspec (2.7.0).
|
9
|
+
|
10
|
+
### Changed
|
11
|
+
|
12
|
+
- Clock auto-selection redux. We choose the first available from:
|
13
|
+
|
14
|
+
1. `CLOCK_UPTIME_RAW` on macOS, faster and higher resolution, also used by Rust
|
15
|
+
2. `CLOCK_MONOTONIC`
|
16
|
+
3. `CLOCK_REALTIME`, a non-monotonic fallback that issues a warning on startup
|
17
|
+
|
18
|
+
- Slight performance bump for `Duration.measure` on Ruby <= 3.1
|
19
|
+
|
20
|
+
## [0.8.1] - 2023-09-18
|
21
|
+
|
22
|
+
### Changed
|
23
|
+
|
24
|
+
- After further consideration, return to defaulting to `CLOCK_MONOTONIC` instead
|
25
|
+
of the overly-elaborate auto-selection introduced in 0.8.0.
|
26
|
+
|
27
|
+
### Removed
|
28
|
+
|
29
|
+
- `Instant.clock_name`. No I'm not incrementing to 0.9. It's been a few hours,
|
30
|
+
you're not using it, shut up.
|
31
|
+
|
3
32
|
## [0.8.0] - 2023-09-17
|
4
33
|
|
5
34
|
### Added
|
@@ -165,8 +194,11 @@
|
|
165
194
|
[0.6.1]: https://github.com/Freaky/monotime/commits/v0.6.1
|
166
195
|
[0.7.0]: https://github.com/Freaky/monotime/commits/v0.7.0
|
167
196
|
[0.7.1]: https://github.com/Freaky/monotime/commits/v0.7.0
|
168
|
-
[0.8.0]: https://github.com/Freaky/monotime/commits/v0.
|
197
|
+
[0.8.0]: https://github.com/Freaky/monotime/commits/v0.8.0
|
198
|
+
[0.8.1]: https://github.com/Freaky/monotime/commits/v0.8.1
|
199
|
+
[0.8.2]: https://github.com/Freaky/monotime/commits/v0.8.2
|
169
200
|
[issue #1]: https://github.com/Freaky/monotime/issues/1
|
201
|
+
[Ruby #16740]: https://bugs.ruby-lang.org/issues/16740
|
170
202
|
[@celsworth]: https://github.com/celsworth
|
171
203
|
[@petergoldstein]: https://github.com/petergoldstein
|
172
|
-
[@fig]: https://github.com/fig
|
204
|
+
[@fig]: https://github.com/fig
|
data/README.md
CHANGED
@@ -171,11 +171,11 @@ The gem is available as open source under the terms of the [MIT License](https:/
|
|
171
171
|
### Core Ruby
|
172
172
|
|
173
173
|
For a zero-dependency alternative upon which `monotime` is based, see
|
174
|
-
[`Process.clock_gettime`](https://
|
174
|
+
[`Process.clock_gettime`](https://www.rubydoc.info/stdlib/core/Process:clock_gettime).
|
175
175
|
|
176
|
-
`Process::CLOCK_MONOTONIC` is a safe default, but other options may offer
|
177
|
-
behaviour in
|
178
|
-
|
176
|
+
`Process::CLOCK_MONOTONIC` is a safe default, but other options may offer higher
|
177
|
+
resolution or alternative behaviour in light of system suspend/resume or NTP
|
178
|
+
frequency skew.
|
179
179
|
|
180
180
|
### Other Gems
|
181
181
|
|
data/lib/monotime/duration.rb
CHANGED
data/lib/monotime/instant.rb
CHANGED
@@ -12,38 +12,16 @@ module Monotime
|
|
12
12
|
include Comparable
|
13
13
|
|
14
14
|
class << self
|
15
|
-
attr_writer :clock_id
|
16
|
-
|
17
|
-
# The symbolic name of the automatically-selected +Process.clock_gettime+
|
18
|
-
# clock id, if available. This will *not* reflect a manually-set +clock_id+.
|
19
|
-
#
|
20
|
-
# @return [Symbol, nil]
|
21
|
-
attr_reader :clock_name
|
22
|
-
|
23
|
-
# The function used to create +Instant+ instances.
|
24
|
-
#
|
25
|
-
# This function must return a +Numeric+, monotonic count of nanoseconds
|
26
|
-
# since a fixed point in the past.
|
27
|
-
#
|
28
|
-
# Defaults to `lambda { Process.clock_gettime(clock_id, :nanosecond) }`.
|
29
|
-
#
|
30
|
-
# @overload monotonic_function=(function)
|
31
|
-
# @param function [#call]
|
32
|
-
attr_accessor :monotonic_function
|
33
|
-
|
34
15
|
# @overload clock_id
|
35
|
-
# The
|
36
|
-
#
|
37
|
-
# Raises +NotImplementedError+ if a suitable monotonic clock source cannot
|
38
|
-
# be found and one has not been specified manually.
|
16
|
+
# The +Process.clock_gettime+ clock id used to create +Instant+ instances
|
17
|
+
# by the default monotonic function.
|
39
18
|
#
|
40
19
|
# @return [Numeric]
|
41
20
|
#
|
42
21
|
# @overload clock_id=(id)
|
43
|
-
# The +Process.clock_gettime+ clock id used to create +Instant+ instances
|
44
|
-
# by the default monotonic function.
|
45
22
|
#
|
46
|
-
#
|
23
|
+
# Override the default +Process.clock_gettime+ clock id. Some potential
|
24
|
+
# choices include but are not limited to:
|
47
25
|
#
|
48
26
|
# * +Process::CLOCK_MONOTONIC_RAW+
|
49
27
|
# * +Process::CLOCK_UPTIME_RAW+
|
@@ -53,56 +31,85 @@ module Monotime
|
|
53
31
|
# * +Process::CLOCK_MONOTONIC_PRECISE+
|
54
32
|
# * +Process::CLOCK_MONOTONIC_FAST+
|
55
33
|
# * +Process::CLOCK_MONOTONIC+
|
34
|
+
# * +:MACH_ABSOLUTE_TIME_BASED_CLOCK_MONOTONIC+
|
35
|
+
# * +:TIMES_BASED_CLOCK_MONOTONIC+
|
56
36
|
#
|
57
|
-
# These are platform-dependant and may vary in resolution,
|
58
|
-
# and behaviour
|
37
|
+
# These are platform-dependant and may vary in resolution, accuracy,
|
38
|
+
# performance, and behaviour in light of system suspend/resume and NTP
|
39
|
+
# frequency skew. They should be selected carefully based on your specific
|
40
|
+
# needs and environment.
|
59
41
|
#
|
60
42
|
# It is possible to set non-monotonic clock sources here. You probably
|
61
43
|
# shouldn't.
|
62
44
|
#
|
63
|
-
# Defaults to auto-
|
45
|
+
# Defaults to auto-selection from whatever is available from:
|
64
46
|
#
|
65
|
-
#
|
66
|
-
|
67
|
-
|
68
|
-
|
47
|
+
# * +CLOCK_UPTIME_RAW+ (if running under macOS)
|
48
|
+
# * +CLOCK_MONOTONIC+
|
49
|
+
# * +CLOCK_REALTIME+ (non-monotonic fallback, issues a run-time warning)
|
50
|
+
#
|
51
|
+
# @param id [Numeric, Symbol]
|
52
|
+
attr_accessor :clock_id
|
53
|
+
|
54
|
+
# The function used to create +Instant+ instances.
|
55
|
+
#
|
56
|
+
# This function must return a +Numeric+, monotonic count of nanoseconds
|
57
|
+
# since a fixed point in the past.
|
58
|
+
#
|
59
|
+
# Defaults to +-> { Process.clock_gettime(clock_id, :nanosecond) }+.
|
60
|
+
#
|
61
|
+
# @overload monotonic_function=(function)
|
62
|
+
# @param function [#call]
|
63
|
+
attr_accessor :monotonic_function
|
69
64
|
|
70
65
|
# Return the claimed resolution of the given clock id or the configured
|
71
66
|
# +clock_id+, as a +Duration+, or +nil+ if invalid.
|
72
67
|
#
|
73
|
-
#
|
74
|
-
|
68
|
+
# Note per Ruby issue #16740, the practical usability of this method is
|
69
|
+
# dubious and non-portable.
|
70
|
+
#
|
71
|
+
# @param clock [Numeric, Symbol] Optional clock id instead of default.
|
72
|
+
def clock_getres(clock = clock_id)
|
75
73
|
Duration.from_nanos(Process.clock_getres(clock, :nanosecond))
|
76
74
|
rescue SystemCallError
|
77
75
|
# suppress errors
|
78
76
|
end
|
79
77
|
|
80
|
-
|
78
|
+
# The symbolic name of the currently-selected +clock_id+, if available.
|
79
|
+
#
|
80
|
+
# @return [Symbol, nil]
|
81
|
+
def clock_name
|
82
|
+
return clock_id if clock_id.is_a? Symbol
|
83
|
+
|
84
|
+
Process.constants.find do |c|
|
85
|
+
c.to_s.start_with?('CLOCK_') && Process.const_get(c) == clock_id
|
86
|
+
end
|
87
|
+
end
|
81
88
|
|
82
|
-
|
83
|
-
name, id, =
|
84
|
-
[
|
85
|
-
:CLOCK_MONOTONIC_RAW, # Linux, not affected by NTP frequency adjustments
|
86
|
-
:CLOCK_UPTIME_RAW, # macOS, not affected by NTP frequency adjustments
|
87
|
-
:CLOCK_UPTIME_PRECISE, # FreeBSD, increments while system is running
|
88
|
-
:CLOCK_UPTIME, # OpenBSD, increments while system is running
|
89
|
-
:CLOCK_MONOTONIC_PRECISE, # FreeBSD, precise monotonic clock
|
90
|
-
:CLOCK_MONOTONIC, # Standard cross-platform monotonic clock
|
91
|
-
]
|
92
|
-
.each_with_index # Used to force a stable sort in min_by
|
93
|
-
.filter { |name, _| Process.const_defined?(name) }
|
94
|
-
.map { |name, index| [name, Process.const_get(name), index] }
|
95
|
-
.filter_map { |clock| clock.insert(2, clock_getres(clock[1])) }
|
96
|
-
.min_by { |clock| clock[2..] } # find smallest resolution and index
|
97
|
-
.tap { |clock| raise NotImplementedError, 'No usable clock' unless clock }
|
89
|
+
private
|
98
90
|
|
99
|
-
|
100
|
-
|
91
|
+
def select_clock_id
|
92
|
+
if RUBY_PLATFORM.include?('darwin') && Process.const_defined?(:CLOCK_UPTIME_RAW)
|
93
|
+
# Offers nanosecond resolution and appears to be slightly faster on two
|
94
|
+
# different Macs (M1 and x64)
|
95
|
+
#
|
96
|
+
# There is also :MACH_ABSOLUTE_TIME_BASED_CLOCK_MONOTONIC which calls
|
97
|
+
# mach_absolute_time() directly, but documentation for that recommends
|
98
|
+
# CLOCK_UPTIME_RAW, and the performance difference is minimal.
|
99
|
+
Process::CLOCK_UPTIME_RAW
|
100
|
+
elsif Process.const_defined?(:CLOCK_MONOTONIC)
|
101
|
+
Process::CLOCK_MONOTONIC
|
102
|
+
else
|
103
|
+
# There is also :TIMES_BASED_CLOCK_MONOTONIC, but having seen it just return
|
104
|
+
# 0 instead of an error on a MSVC build this may be the safer option.
|
105
|
+
warn 'No monotonic clock source detected, falling back to CLOCK_REALTIME'
|
106
|
+
Process::CLOCK_REALTIME
|
107
|
+
end
|
101
108
|
end
|
102
109
|
end
|
103
110
|
|
104
111
|
self.monotonic_function = -> { Process.clock_gettime(clock_id, :nanosecond) }
|
105
|
-
clock_id
|
112
|
+
self.clock_id = select_clock_id
|
106
113
|
|
107
114
|
# Create a new +Instant+ from an optional nanosecond measurement.
|
108
115
|
#
|
data/lib/monotime/version.rb
CHANGED
data/monotime.gemspec
CHANGED
@@ -13,6 +13,8 @@ Gem::Specification.new do |spec|
|
|
13
13
|
spec.homepage = "https://github.com/Freaky/monotime"
|
14
14
|
spec.license = "MIT"
|
15
15
|
|
16
|
+
spec.required_ruby_version = '>= 2.7.0'
|
17
|
+
|
16
18
|
# Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
|
17
19
|
# to allow pushing to a single host or delete this section to allow pushing to any host.
|
18
20
|
if spec.respond_to?(:metadata)
|
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.8.
|
4
|
+
version: 0.8.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Thomas Hurst
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-09-
|
11
|
+
date: 2023-09-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -102,14 +102,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
102
102
|
requirements:
|
103
103
|
- - ">="
|
104
104
|
- !ruby/object:Gem::Version
|
105
|
-
version:
|
105
|
+
version: 2.7.0
|
106
106
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
107
107
|
requirements:
|
108
108
|
- - ">="
|
109
109
|
- !ruby/object:Gem::Version
|
110
110
|
version: '0'
|
111
111
|
requirements: []
|
112
|
-
rubygems_version: 3.4.
|
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
|