monotime 0.8.0 → 0.8.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|