timers 4.3.1 → 4.3.4
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
- checksums.yaml.gz.sig +4 -0
- data/lib/timers/events.rb +36 -68
- data/lib/timers/group.rb +26 -40
- data/lib/timers/interval.rb +2 -19
- data/lib/timers/priority_heap.rb +146 -0
- data/lib/timers/timer.rb +47 -58
- data/lib/timers/version.rb +5 -20
- data/lib/timers/wait.rb +13 -27
- data/lib/timers.rb +14 -19
- data/license.md +48 -0
- data/readme.md +110 -0
- data.tar.gz.sig +0 -0
- metadata +98 -9
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6aaa0d481ea83db607add1809f3f5d96b085bddf5bda6fa17165c18316c4c527
|
4
|
+
data.tar.gz: 8995d8268bd1c49b047e0fe0d1bf252d8c943962d05eee4026601b952cacc339
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3d5a69bc7f7e32e02365476d9a25e97dbe72c572497874356603554ecc28f5ee88821af1a2bfd4239a232f0d7a9ef0048c45a1909eefa7faae3619c51c3ec87a
|
7
|
+
data.tar.gz: 6521553ef5271c9191aa0dc4f23a65c3eb776293273784e46597bda0a92ae0d97aa915e4f9c25869b8923f516fe23ed2bf389abf34e1cb76ac6f5484d6d927da
|
checksums.yaml.gz.sig
ADDED
@@ -0,0 +1,4 @@
|
|
1
|
+
@BC�S���rr�H�rW
|
2
|
+
���۳�Jc�ݠb�1ɥY���(���.W����Li����"^�'���&��.����y�2Sk\Ї7�?.q(IK��(��?�:�s���A�(L������f8)��(0�[�
|
3
|
+
RʞY��s����`�L[�D*t��R}MG�?�����l�J���ߩTu���mx��G��
|
4
|
+
�W8��� u��4ټn_�D|N���[����m�1��l�U�a�Y�N.�?' 0fTtH��_r邧��i�KW�^��س�ڲN�R�o�2��~e$'��=��%���@�� H��5ŭ#�
|
data/lib/timers/events.rb
CHANGED
@@ -1,143 +1,111 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
#
|
4
|
-
#
|
5
|
-
#
|
6
|
-
#
|
7
|
-
#
|
8
|
-
#
|
9
|
-
#
|
10
|
-
# furnished to do so, subject to the following conditions:
|
11
|
-
#
|
12
|
-
# The above copyright notice and this permission notice shall be included in
|
13
|
-
# all copies or substantial portions of the Software.
|
14
|
-
#
|
15
|
-
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
-
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
-
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
-
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
-
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
-
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
-
# THE SOFTWARE.
|
3
|
+
# Released under the MIT License.
|
4
|
+
# Copyright, 2014-2022, by Samuel Williams.
|
5
|
+
# Copyright, 2014-2016, by Tony Arcieri.
|
6
|
+
# Copyright, 2014, by Lavir the Whiolet.
|
7
|
+
# Copyright, 2015, by Utenmiki.
|
8
|
+
# Copyright, 2015, by Donovan Keme.
|
9
|
+
# Copyright, 2021, by Wander Hillen.
|
22
10
|
|
23
11
|
require_relative "timer"
|
12
|
+
require_relative "priority_heap"
|
24
13
|
|
25
14
|
module Timers
|
26
|
-
# Maintains
|
15
|
+
# Maintains a PriorityHeap of events ordered on time, which can be cancelled.
|
27
16
|
class Events
|
28
17
|
# Represents a cancellable handle for a specific timer event.
|
29
18
|
class Handle
|
19
|
+
include Comparable
|
20
|
+
|
30
21
|
def initialize(time, callback)
|
31
22
|
@time = time
|
32
23
|
@callback = callback
|
33
24
|
end
|
34
|
-
|
25
|
+
|
35
26
|
# The absolute time that the handle should be fired at.
|
36
27
|
attr_reader :time
|
37
|
-
|
28
|
+
|
38
29
|
# Cancel this timer, O(1).
|
39
30
|
def cancel!
|
40
31
|
# The simplest way to keep track of cancelled status is to nullify the
|
41
32
|
# callback. This should also be optimal for garbage collection.
|
42
33
|
@callback = nil
|
43
34
|
end
|
44
|
-
|
35
|
+
|
45
36
|
# Has this timer been cancelled? Cancelled timer's don't fire.
|
46
37
|
def cancelled?
|
47
38
|
@callback.nil?
|
48
39
|
end
|
49
|
-
|
50
|
-
def
|
51
|
-
@time
|
52
|
-
end
|
53
|
-
|
54
|
-
def >= other
|
55
|
-
@time >= other.to_f
|
56
|
-
end
|
57
|
-
|
58
|
-
def to_f
|
59
|
-
@time
|
40
|
+
|
41
|
+
def <=> other
|
42
|
+
@time <=> other.time
|
60
43
|
end
|
61
|
-
|
44
|
+
|
62
45
|
# Fire the callback if not cancelled with the given time parameter.
|
63
46
|
def fire(time)
|
64
47
|
@callback.call(time) if @callback
|
65
48
|
end
|
66
49
|
end
|
67
|
-
|
50
|
+
|
68
51
|
def initialize
|
69
52
|
# A sequence of handles, maintained in sorted order, future to present.
|
70
53
|
# @sequence.last is the next event to be fired.
|
71
|
-
@sequence =
|
54
|
+
@sequence = PriorityHeap.new
|
72
55
|
@queue = []
|
73
56
|
end
|
74
|
-
|
57
|
+
|
75
58
|
# Add an event at the given time.
|
76
59
|
def schedule(time, callback)
|
60
|
+
flush!
|
61
|
+
|
77
62
|
handle = Handle.new(time.to_f, callback)
|
78
63
|
|
79
64
|
@queue << handle
|
80
65
|
|
81
66
|
return handle
|
82
67
|
end
|
83
|
-
|
68
|
+
|
84
69
|
# Returns the first non-cancelled handle.
|
85
70
|
def first
|
86
71
|
merge!
|
87
72
|
|
88
|
-
while (handle = @sequence.
|
73
|
+
while (handle = @sequence.peek)
|
89
74
|
return handle unless handle.cancelled?
|
90
75
|
@sequence.pop
|
91
76
|
end
|
92
77
|
end
|
93
|
-
|
78
|
+
|
94
79
|
# Returns the number of pending (possibly cancelled) events.
|
95
80
|
def size
|
96
81
|
@sequence.size + @queue.size
|
97
82
|
end
|
98
|
-
|
83
|
+
|
99
84
|
# Fire all handles for which Handle#time is less than the given time.
|
100
85
|
def fire(time)
|
101
86
|
merge!
|
102
87
|
|
103
|
-
while handle = @sequence.
|
88
|
+
while handle = @sequence.peek and handle.time <= time
|
104
89
|
@sequence.pop
|
105
90
|
handle.fire(time)
|
106
91
|
end
|
107
92
|
end
|
108
|
-
|
93
|
+
|
109
94
|
private
|
110
|
-
|
95
|
+
|
96
|
+
# Move all non-cancelled timers from the pending queue to the priority heap
|
111
97
|
def merge!
|
112
98
|
while handle = @queue.pop
|
113
99
|
next if handle.cancelled?
|
114
100
|
|
115
|
-
|
116
|
-
|
117
|
-
if current_handle = @sequence[index] and current_handle.cancelled?
|
118
|
-
# puts "Replacing handle at index: #{index} due to cancellation in array containing #{@sequence.size} item(s)."
|
119
|
-
@sequence[index] = handle
|
120
|
-
else
|
121
|
-
# puts "Inserting handle at index: #{index} in array containing #{@sequence.size} item(s)."
|
122
|
-
@sequence.insert(index, handle)
|
123
|
-
end
|
101
|
+
@sequence.push(handle)
|
124
102
|
end
|
125
103
|
end
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
while l < u
|
131
|
-
m = l + (u - l).div(2)
|
132
|
-
|
133
|
-
if a[m] >= e
|
134
|
-
l = m + 1
|
135
|
-
else
|
136
|
-
u = m
|
137
|
-
end
|
104
|
+
|
105
|
+
def flush!
|
106
|
+
while @queue.last&.cancelled?
|
107
|
+
@queue.pop
|
138
108
|
end
|
139
|
-
|
140
|
-
l
|
141
109
|
end
|
142
110
|
end
|
143
111
|
end
|
data/lib/timers/group.rb
CHANGED
@@ -1,24 +1,10 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
#
|
4
|
-
#
|
5
|
-
#
|
6
|
-
#
|
7
|
-
#
|
8
|
-
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
-
# copies of the Software, and to permit persons to whom the Software is
|
10
|
-
# furnished to do so, subject to the following conditions:
|
11
|
-
#
|
12
|
-
# The above copyright notice and this permission notice shall be included in
|
13
|
-
# all copies or substantial portions of the Software.
|
14
|
-
#
|
15
|
-
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
-
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
-
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
-
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
-
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
-
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
-
# THE SOFTWARE.
|
3
|
+
# Released under the MIT License.
|
4
|
+
# Copyright, 2014-2022, by Samuel Williams.
|
5
|
+
# Copyright, 2014-2016, by Tony Arcieri.
|
6
|
+
# Copyright, 2015, by Donovan Keme.
|
7
|
+
# Copyright, 2015, by Tommy Ong Gia Phu.
|
22
8
|
|
23
9
|
require "set"
|
24
10
|
require "forwardable"
|
@@ -31,62 +17,62 @@ module Timers
|
|
31
17
|
# A collection of timers which may fire at different times
|
32
18
|
class Group
|
33
19
|
include Enumerable
|
34
|
-
|
20
|
+
|
35
21
|
extend Forwardable
|
36
22
|
def_delegators :@timers, :each, :empty?
|
37
|
-
|
23
|
+
|
38
24
|
def initialize
|
39
25
|
@events = Events.new
|
40
|
-
|
26
|
+
|
41
27
|
@timers = Set.new
|
42
28
|
@paused_timers = Set.new
|
43
|
-
|
29
|
+
|
44
30
|
@interval = Interval.new
|
45
31
|
@interval.start
|
46
32
|
end
|
47
|
-
|
33
|
+
|
48
34
|
# Scheduled events:
|
49
35
|
attr_reader :events
|
50
|
-
|
36
|
+
|
51
37
|
# Active timers:
|
52
38
|
attr_reader :timers
|
53
|
-
|
39
|
+
|
54
40
|
# Paused timers:
|
55
41
|
attr_reader :paused_timers
|
56
|
-
|
42
|
+
|
57
43
|
# Call the given block after the given interval. The first argument will be
|
58
44
|
# the time at which the group was asked to fire timers for.
|
59
45
|
def after(interval, &block)
|
60
46
|
Timer.new(self, interval, false, &block)
|
61
47
|
end
|
62
|
-
|
48
|
+
|
63
49
|
# Call the given block immediately, and then after the given interval. The first
|
64
50
|
# argument will be the time at which the group was asked to fire timers for.
|
65
51
|
def now_and_after(interval, &block)
|
66
52
|
yield
|
67
53
|
after(interval, &block)
|
68
54
|
end
|
69
|
-
|
55
|
+
|
70
56
|
# Call the given block periodically at the given interval. The first
|
71
57
|
# argument will be the time at which the group was asked to fire timers for.
|
72
58
|
def every(interval, recur = true, &block)
|
73
59
|
Timer.new(self, interval, recur, &block)
|
74
60
|
end
|
75
|
-
|
61
|
+
|
76
62
|
# Call the given block immediately, and then periodically at the given interval. The first
|
77
63
|
# argument will be the time at which the group was asked to fire timers for.
|
78
64
|
def now_and_every(interval, recur = true, &block)
|
79
65
|
yield
|
80
66
|
every(interval, recur, &block)
|
81
67
|
end
|
82
|
-
|
68
|
+
|
83
69
|
# Wait for the next timer and fire it. Can take a block, which should behave
|
84
70
|
# like sleep(n), except that n may be nil (sleep forever) or a negative
|
85
71
|
# number (fire immediately after return).
|
86
72
|
def wait
|
87
73
|
if block_given?
|
88
74
|
yield wait_interval
|
89
|
-
|
75
|
+
|
90
76
|
while (interval = wait_interval) && interval > 0
|
91
77
|
yield interval
|
92
78
|
end
|
@@ -99,7 +85,7 @@ module Timers
|
|
99
85
|
|
100
86
|
fire
|
101
87
|
end
|
102
|
-
|
88
|
+
|
103
89
|
# Interval to wait until when the next timer will fire.
|
104
90
|
# - nil: no timers
|
105
91
|
# - -ve: timers expired already
|
@@ -109,36 +95,36 @@ module Timers
|
|
109
95
|
handle = @events.first
|
110
96
|
handle.time - Float(offset) if handle
|
111
97
|
end
|
112
|
-
|
98
|
+
|
113
99
|
# Fire all timers that are ready.
|
114
100
|
def fire(offset = current_offset)
|
115
101
|
@events.fire(offset)
|
116
102
|
end
|
117
|
-
|
103
|
+
|
118
104
|
# Pause all timers.
|
119
105
|
def pause
|
120
106
|
@timers.dup.each(&:pause)
|
121
107
|
end
|
122
|
-
|
108
|
+
|
123
109
|
# Resume all timers.
|
124
110
|
def resume
|
125
111
|
@paused_timers.dup.each(&:resume)
|
126
112
|
end
|
127
|
-
|
113
|
+
|
128
114
|
alias continue resume
|
129
|
-
|
115
|
+
|
130
116
|
# Delay all timers.
|
131
117
|
def delay(seconds)
|
132
118
|
@timers.each do |timer|
|
133
119
|
timer.delay(seconds)
|
134
120
|
end
|
135
121
|
end
|
136
|
-
|
122
|
+
|
137
123
|
# Cancel all timers.
|
138
124
|
def cancel
|
139
125
|
@timers.dup.each(&:cancel)
|
140
126
|
end
|
141
|
-
|
127
|
+
|
142
128
|
# The group's current time.
|
143
129
|
def current_offset
|
144
130
|
@interval.to_f
|
data/lib/timers/interval.rb
CHANGED
@@ -1,24 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
#
|
4
|
-
#
|
5
|
-
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
-
# of this software and associated documentation files (the "Software"), to deal
|
7
|
-
# in the Software without restriction, including without limitation the rights
|
8
|
-
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
-
# copies of the Software, and to permit persons to whom the Software is
|
10
|
-
# furnished to do so, subject to the following conditions:
|
11
|
-
#
|
12
|
-
# The above copyright notice and this permission notice shall be included in
|
13
|
-
# all copies or substantial portions of the Software.
|
14
|
-
#
|
15
|
-
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
-
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
-
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
-
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
-
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
-
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
-
# THE SOFTWARE.
|
3
|
+
# Released under the MIT License.
|
4
|
+
# Copyright, 2018-2022, by Samuel Williams.
|
22
5
|
|
23
6
|
module Timers
|
24
7
|
# A collection of timers which may fire at different times
|
@@ -0,0 +1,146 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Released under the MIT License.
|
4
|
+
# Copyright, 2021, by Wander Hillen.
|
5
|
+
# Copyright, 2021-2022, by Samuel Williams.
|
6
|
+
|
7
|
+
module Timers
|
8
|
+
# A priority queue implementation using a standard binary minheap. It uses straight comparison
|
9
|
+
# of its contents to determine priority. This works because a Handle from Timers::Events implements
|
10
|
+
# the '<' operation by comparing the expiry time.
|
11
|
+
# See <https://en.wikipedia.org/wiki/Binary_heap> for explanations of the main methods.
|
12
|
+
class PriorityHeap
|
13
|
+
def initialize
|
14
|
+
# The heap is represented with an array containing a binary tree. See
|
15
|
+
# https://en.wikipedia.org/wiki/Binary_heap#Heap_implementation for how this array
|
16
|
+
# is built up.
|
17
|
+
@contents = []
|
18
|
+
end
|
19
|
+
|
20
|
+
# Returns the earliest timer or nil if the heap is empty.
|
21
|
+
def peek
|
22
|
+
@contents[0]
|
23
|
+
end
|
24
|
+
|
25
|
+
# Returns the number of elements in the heap
|
26
|
+
def size
|
27
|
+
@contents.size
|
28
|
+
end
|
29
|
+
|
30
|
+
# Returns the earliest timer if the heap is non-empty and removes it from the heap.
|
31
|
+
# Returns nil if the heap is empty. (and doesn't change the heap in that case)
|
32
|
+
def pop
|
33
|
+
# If the heap is empty:
|
34
|
+
if @contents.empty?
|
35
|
+
return nil
|
36
|
+
end
|
37
|
+
|
38
|
+
# If we have only one item, no swapping is required:
|
39
|
+
if @contents.size == 1
|
40
|
+
return @contents.pop
|
41
|
+
end
|
42
|
+
|
43
|
+
# Take the root of the tree:
|
44
|
+
value = @contents[0]
|
45
|
+
|
46
|
+
# Remove the last item in the tree:
|
47
|
+
last = @contents.pop
|
48
|
+
|
49
|
+
# Overwrite the root of the tree with the item:
|
50
|
+
@contents[0] = last
|
51
|
+
|
52
|
+
# Bubble it down into place:
|
53
|
+
bubble_down(0)
|
54
|
+
|
55
|
+
# validate!
|
56
|
+
|
57
|
+
return value
|
58
|
+
end
|
59
|
+
|
60
|
+
# Inserts a new timer into the heap, then rearranges elements until the heap invariant is true again.
|
61
|
+
def push(element)
|
62
|
+
# Insert the item at the end of the heap:
|
63
|
+
@contents.push(element)
|
64
|
+
|
65
|
+
# Bubble it up into position:
|
66
|
+
bubble_up(@contents.size - 1)
|
67
|
+
|
68
|
+
# validate!
|
69
|
+
|
70
|
+
return self
|
71
|
+
end
|
72
|
+
|
73
|
+
# Empties out the heap, discarding all elements
|
74
|
+
def clear!
|
75
|
+
@contents = []
|
76
|
+
end
|
77
|
+
|
78
|
+
# Validate the heap invariant. Every element except the root must not be smaller than
|
79
|
+
# its parent element. Note that it MAY be equal.
|
80
|
+
def valid?
|
81
|
+
# notice we skip index 0 on purpose, because it has no parent
|
82
|
+
(1..(@contents.size - 1)).all? { |e| @contents[e] >= @contents[(e - 1) / 2] }
|
83
|
+
end
|
84
|
+
|
85
|
+
private
|
86
|
+
|
87
|
+
def swap(i, j)
|
88
|
+
@contents[i], @contents[j] = @contents[j], @contents[i]
|
89
|
+
end
|
90
|
+
|
91
|
+
def bubble_up(index)
|
92
|
+
parent_index = (index - 1) / 2 # watch out, integer division!
|
93
|
+
|
94
|
+
while index > 0 && @contents[index] < @contents[parent_index]
|
95
|
+
# if the node has a smaller value than its parent, swap these nodes
|
96
|
+
# to uphold the minheap invariant and update the index of the 'current'
|
97
|
+
# node. If the node is already at index 0, we can also stop because that
|
98
|
+
# is the root of the heap.
|
99
|
+
# swap(index, parent_index)
|
100
|
+
@contents[index], @contents[parent_index] = @contents[parent_index], @contents[index]
|
101
|
+
|
102
|
+
index = parent_index
|
103
|
+
parent_index = (index - 1) / 2 # watch out, integer division!
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
def bubble_down(index)
|
108
|
+
swap_value = 0
|
109
|
+
swap_index = nil
|
110
|
+
|
111
|
+
while true
|
112
|
+
left_index = (2 * index) + 1
|
113
|
+
left_value = @contents[left_index]
|
114
|
+
|
115
|
+
if left_value.nil?
|
116
|
+
# This node has no children so it can't bubble down any further.
|
117
|
+
# We're done here!
|
118
|
+
return
|
119
|
+
end
|
120
|
+
|
121
|
+
# Determine which of the child nodes has the smallest value:
|
122
|
+
right_index = left_index + 1
|
123
|
+
right_value = @contents[right_index]
|
124
|
+
|
125
|
+
if right_value.nil? or right_value > left_value
|
126
|
+
swap_value = left_value
|
127
|
+
swap_index = left_index
|
128
|
+
else
|
129
|
+
swap_value = right_value
|
130
|
+
swap_index = right_index
|
131
|
+
end
|
132
|
+
|
133
|
+
if @contents[index] < swap_value
|
134
|
+
# No need to swap, the minheap invariant is already satisfied:
|
135
|
+
return
|
136
|
+
else
|
137
|
+
# At least one of the child node has a smaller value than the current node, swap current node with that child and update current node for if it might need to bubble down even further:
|
138
|
+
# swap(index, swap_index)
|
139
|
+
@contents[index], @contents[swap_index] = @contents[swap_index], @contents[index]
|
140
|
+
|
141
|
+
index = swap_index
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
data/lib/timers/timer.rb
CHANGED
@@ -1,24 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
#
|
4
|
-
#
|
5
|
-
#
|
6
|
-
#
|
7
|
-
#
|
8
|
-
#
|
9
|
-
# copies of the Software, and to permit persons to whom the Software is
|
10
|
-
# furnished to do so, subject to the following conditions:
|
11
|
-
#
|
12
|
-
# The above copyright notice and this permission notice shall be included in
|
13
|
-
# all copies or substantial portions of the Software.
|
14
|
-
#
|
15
|
-
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
-
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
-
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
-
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
-
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
-
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
-
# THE SOFTWARE.
|
3
|
+
# Released under the MIT License.
|
4
|
+
# Copyright, 2014-2022, by Samuel Williams.
|
5
|
+
# Copyright, 2014-2017, by Tony Arcieri.
|
6
|
+
# Copyright, 2014, by Utenmiki.
|
7
|
+
# Copyright, 2014, by Lin Jen-Shin.
|
8
|
+
# Copyright, 2017, by Vít Ondruch.
|
22
9
|
|
23
10
|
module Timers
|
24
11
|
# An individual timer set to fire a given proc at a given time. A timer is
|
@@ -29,66 +16,66 @@ module Timers
|
|
29
16
|
class Timer
|
30
17
|
include Comparable
|
31
18
|
attr_reader :interval, :offset, :recurring
|
32
|
-
|
19
|
+
|
33
20
|
def initialize(group, interval, recurring = false, offset = nil, &block)
|
34
21
|
@group = group
|
35
|
-
|
22
|
+
|
36
23
|
@interval = interval
|
37
24
|
@recurring = recurring
|
38
25
|
@block = block
|
39
26
|
@offset = offset
|
40
|
-
|
27
|
+
|
41
28
|
@handle = nil
|
42
|
-
|
29
|
+
|
43
30
|
# If a start offset was supplied, use that, otherwise use the current timers offset.
|
44
31
|
reset(@offset || @group.current_offset)
|
45
32
|
end
|
46
|
-
|
33
|
+
|
47
34
|
def paused?
|
48
35
|
@group.paused_timers.include? self
|
49
36
|
end
|
50
|
-
|
37
|
+
|
51
38
|
def pause
|
52
39
|
return if paused?
|
53
|
-
|
40
|
+
|
54
41
|
@group.timers.delete self
|
55
42
|
@group.paused_timers.add self
|
56
|
-
|
43
|
+
|
57
44
|
@handle.cancel! if @handle
|
58
45
|
@handle = nil
|
59
46
|
end
|
60
|
-
|
47
|
+
|
61
48
|
def resume
|
62
49
|
return unless paused?
|
63
|
-
|
50
|
+
|
64
51
|
@group.paused_timers.delete self
|
65
|
-
|
52
|
+
|
66
53
|
# This will add us back to the group:
|
67
54
|
reset
|
68
55
|
end
|
69
|
-
|
56
|
+
|
70
57
|
alias continue resume
|
71
|
-
|
58
|
+
|
72
59
|
# Extend this timer
|
73
60
|
def delay(seconds)
|
74
61
|
@handle.cancel! if @handle
|
75
|
-
|
62
|
+
|
76
63
|
@offset += seconds
|
77
|
-
|
64
|
+
|
78
65
|
@handle = @group.events.schedule(@offset, self)
|
79
66
|
end
|
80
|
-
|
67
|
+
|
81
68
|
# Cancel this timer. Do not call while paused.
|
82
69
|
def cancel
|
83
70
|
return unless @handle
|
84
|
-
|
71
|
+
|
85
72
|
@handle.cancel! if @handle
|
86
73
|
@handle = nil
|
87
|
-
|
74
|
+
|
88
75
|
# This timer is no longer valid:
|
89
76
|
@group.timers.delete self if @group
|
90
77
|
end
|
91
|
-
|
78
|
+
|
92
79
|
# Reset this timer. Do not call while paused.
|
93
80
|
# @param offset [Numeric] the duration to add to the timer.
|
94
81
|
def reset(offset = @group.current_offset)
|
@@ -99,12 +86,12 @@ module Timers
|
|
99
86
|
else
|
100
87
|
@group.timers << self
|
101
88
|
end
|
102
|
-
|
89
|
+
|
103
90
|
@offset = Float(offset) + @interval
|
104
|
-
|
91
|
+
|
105
92
|
@handle = @group.events.schedule(@offset, self)
|
106
93
|
end
|
107
|
-
|
94
|
+
|
108
95
|
# Fire the block.
|
109
96
|
def fire(offset = @group.current_offset)
|
110
97
|
if recurring == :strict
|
@@ -115,36 +102,38 @@ module Timers
|
|
115
102
|
else
|
116
103
|
@offset = offset
|
117
104
|
end
|
118
|
-
|
105
|
+
|
119
106
|
@block.call(offset, self)
|
120
|
-
|
107
|
+
|
121
108
|
cancel unless recurring
|
122
109
|
end
|
123
|
-
|
110
|
+
|
124
111
|
alias call fire
|
125
|
-
|
112
|
+
|
126
113
|
# Number of seconds until next fire / since last fire
|
127
114
|
def fires_in
|
128
115
|
@offset - @group.current_offset if @offset
|
129
116
|
end
|
130
|
-
|
117
|
+
|
131
118
|
# Inspect a timer
|
132
119
|
def inspect
|
133
|
-
|
134
|
-
|
120
|
+
buffer = "#{to_s[0..-2]} ".dup
|
121
|
+
|
135
122
|
if @offset
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
123
|
+
if fires_in >= 0
|
124
|
+
buffer << "fires in #{fires_in} seconds"
|
125
|
+
else
|
126
|
+
buffer << "fired #{fires_in.abs} seconds ago"
|
127
|
+
end
|
128
|
+
|
129
|
+
buffer << ", recurs every #{interval}" if recurring
|
143
130
|
else
|
144
|
-
|
131
|
+
buffer << "dead"
|
145
132
|
end
|
146
|
-
|
147
|
-
|
133
|
+
|
134
|
+
buffer << ">"
|
135
|
+
|
136
|
+
return buffer
|
148
137
|
end
|
149
138
|
end
|
150
139
|
end
|
data/lib/timers/version.rb
CHANGED
@@ -1,25 +1,10 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
#
|
4
|
-
#
|
5
|
-
#
|
6
|
-
#
|
7
|
-
# in the Software without restriction, including without limitation the rights
|
8
|
-
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
-
# copies of the Software, and to permit persons to whom the Software is
|
10
|
-
# furnished to do so, subject to the following conditions:
|
11
|
-
#
|
12
|
-
# The above copyright notice and this permission notice shall be included in
|
13
|
-
# all copies or substantial portions of the Software.
|
14
|
-
#
|
15
|
-
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
-
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
-
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
-
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
-
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
-
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
-
# THE SOFTWARE.
|
3
|
+
# Released under the MIT License.
|
4
|
+
# Copyright, 2012-2016, by Tony Arcieri.
|
5
|
+
# Copyright, 2014-2022, by Samuel Williams.
|
6
|
+
# Copyright, 2015, by Donovan Keme.
|
22
7
|
|
23
8
|
module Timers
|
24
|
-
VERSION = "4.3.
|
9
|
+
VERSION = "4.3.4"
|
25
10
|
end
|
data/lib/timers/wait.rb
CHANGED
@@ -1,24 +1,10 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
#
|
4
|
-
#
|
5
|
-
#
|
6
|
-
#
|
7
|
-
#
|
8
|
-
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
-
# copies of the Software, and to permit persons to whom the Software is
|
10
|
-
# furnished to do so, subject to the following conditions:
|
11
|
-
#
|
12
|
-
# The above copyright notice and this permission notice shall be included in
|
13
|
-
# all copies or substantial portions of the Software.
|
14
|
-
#
|
15
|
-
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
-
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
-
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
-
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
-
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
-
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
-
# THE SOFTWARE.
|
3
|
+
# Released under the MIT License.
|
4
|
+
# Copyright, 2014-2022, by Samuel Williams.
|
5
|
+
# Copyright, 2014-2016, by Tony Arcieri.
|
6
|
+
# Copyright, 2015, by Utenmiki.
|
7
|
+
# Copyright, 2015, by Donovan Keme.
|
22
8
|
|
23
9
|
require_relative "interval"
|
24
10
|
|
@@ -28,7 +14,7 @@ module Timers
|
|
28
14
|
def self.for(duration, &block)
|
29
15
|
if duration
|
30
16
|
timeout = new(duration)
|
31
|
-
|
17
|
+
|
32
18
|
timeout.while_time_remaining(&block)
|
33
19
|
else
|
34
20
|
loop do
|
@@ -36,31 +22,31 @@ module Timers
|
|
36
22
|
end
|
37
23
|
end
|
38
24
|
end
|
39
|
-
|
25
|
+
|
40
26
|
def initialize(duration)
|
41
27
|
@duration = duration
|
42
28
|
@remaining = true
|
43
29
|
end
|
44
|
-
|
30
|
+
|
45
31
|
attr_reader :duration
|
46
32
|
attr_reader :remaining
|
47
|
-
|
33
|
+
|
48
34
|
# Yields while time remains for work to be done:
|
49
35
|
def while_time_remaining
|
50
36
|
@interval = Interval.new
|
51
37
|
@interval.start
|
52
|
-
|
38
|
+
|
53
39
|
yield @remaining while time_remaining?
|
54
40
|
ensure
|
55
41
|
@interval.stop
|
56
42
|
@interval = nil
|
57
43
|
end
|
58
|
-
|
44
|
+
|
59
45
|
private
|
60
|
-
|
46
|
+
|
61
47
|
def time_remaining?
|
62
48
|
@remaining = (@duration - @interval.to_f)
|
63
|
-
|
49
|
+
|
64
50
|
@remaining > 0
|
65
51
|
end
|
66
52
|
end
|
data/lib/timers.rb
CHANGED
@@ -1,24 +1,19 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
#
|
4
|
-
#
|
5
|
-
#
|
6
|
-
#
|
7
|
-
#
|
8
|
-
#
|
9
|
-
#
|
10
|
-
#
|
11
|
-
#
|
12
|
-
#
|
13
|
-
#
|
14
|
-
#
|
15
|
-
#
|
16
|
-
#
|
17
|
-
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
-
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
-
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
-
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
-
# THE SOFTWARE.
|
3
|
+
# Released under the MIT License.
|
4
|
+
# Copyright, 2012-2016, by Tony Arcieri.
|
5
|
+
# Copyright, 2012, by Ryan LeCompte.
|
6
|
+
# Copyright, 2012, by Nicholas Evans.
|
7
|
+
# Copyright, 2012, by Dimitrij Denissenko.
|
8
|
+
# Copyright, 2013, by Chuck Remes.
|
9
|
+
# Copyright, 2013, by Ron Evans.
|
10
|
+
# Copyright, 2013, by Sean Gregory.
|
11
|
+
# Copyright, 2013, by Utenmiki.
|
12
|
+
# Copyright, 2013, by Jeremy Hinegardner.
|
13
|
+
# Copyright, 2014, by Larry Lv.
|
14
|
+
# Copyright, 2014, by Bruno Enten.
|
15
|
+
# Copyright, 2014-2022, by Samuel Williams.
|
16
|
+
# Copyright, 2014, by Mike Bourgeous.
|
22
17
|
|
23
18
|
require_relative "timers/version"
|
24
19
|
|
data/license.md
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
# MIT License
|
2
|
+
|
3
|
+
Copyright, 2012-2017, by Tony Arcieri.
|
4
|
+
Copyright, 2012, by Ryan LeCompte.
|
5
|
+
Copyright, 2012, by Jesse Cooke.
|
6
|
+
Copyright, 2012, by Nicholas Evans.
|
7
|
+
Copyright, 2012, by Dimitrij Denissenko.
|
8
|
+
Copyright, 2013, by Chuck Remes.
|
9
|
+
Copyright, 2013, by Ron Evans.
|
10
|
+
Copyright, 2013, by Sean Gregory.
|
11
|
+
Copyright, 2013-2015, by Utenmiki.
|
12
|
+
Copyright, 2013, by Jeremy Hinegardner.
|
13
|
+
Copyright, 2014, by Larry Lv.
|
14
|
+
Copyright, 2014, by Bruno Enten.
|
15
|
+
Copyright, 2014-2022, by Samuel Williams.
|
16
|
+
Copyright, 2014, by Mike Bourgeous.
|
17
|
+
Copyright, 2014, by Klaus Trainer.
|
18
|
+
Copyright, 2014, by Lin Jen-Shin.
|
19
|
+
Copyright, 2014, by Lavir the Whiolet.
|
20
|
+
Copyright, 2015-2016, by Donovan Keme.
|
21
|
+
Copyright, 2015, by Tommy Ong Gia Phu.
|
22
|
+
Copyright, 2015, by Will Jessop.
|
23
|
+
Copyright, 2016, by Ryunosuke SATO.
|
24
|
+
Copyright, 2016, by Atul Bhosale.
|
25
|
+
Copyright, 2016, by Feram.
|
26
|
+
Copyright, 2017, by Vít Ondruch.
|
27
|
+
Copyright, 2017-2020, by Olle Jonsson.
|
28
|
+
Copyright, 2020, by Tim Smith.
|
29
|
+
Copyright, 2021, by Wander Hillen.
|
30
|
+
Copyright, 2022, by Yoshiki Takagi.
|
31
|
+
|
32
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
33
|
+
of this software and associated documentation files (the "Software"), to deal
|
34
|
+
in the Software without restriction, including without limitation the rights
|
35
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
36
|
+
copies of the Software, and to permit persons to whom the Software is
|
37
|
+
furnished to do so, subject to the following conditions:
|
38
|
+
|
39
|
+
The above copyright notice and this permission notice shall be included in all
|
40
|
+
copies or substantial portions of the Software.
|
41
|
+
|
42
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
43
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
44
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
45
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
46
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
47
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
48
|
+
SOFTWARE.
|
data/readme.md
ADDED
@@ -0,0 +1,110 @@
|
|
1
|
+
# Timers
|
2
|
+
|
3
|
+
Collections of one-shot and periodic timers, intended for use with event loops such as [async](https://github.com/socketry/async).
|
4
|
+
|
5
|
+
[](https://github.com/socketry/timers/actions?workflow=Test)
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
Add this line to your application's Gemfile:
|
10
|
+
|
11
|
+
``` ruby
|
12
|
+
gem 'timers'
|
13
|
+
```
|
14
|
+
|
15
|
+
And then execute:
|
16
|
+
|
17
|
+
$ bundle
|
18
|
+
|
19
|
+
Or install it yourself as:
|
20
|
+
|
21
|
+
$ gem install timers
|
22
|
+
|
23
|
+
## Usage
|
24
|
+
|
25
|
+
Create a new timer group with `Timers::Group.new`:
|
26
|
+
|
27
|
+
``` ruby
|
28
|
+
require 'timers'
|
29
|
+
|
30
|
+
timers = Timers::Group.new
|
31
|
+
```
|
32
|
+
|
33
|
+
Schedule a proc to run after 5 seconds with `Timers::Group#after`:
|
34
|
+
|
35
|
+
``` ruby
|
36
|
+
five_second_timer = timers.after(5) { puts "Take five" }
|
37
|
+
```
|
38
|
+
|
39
|
+
The `five_second_timer` variable is now bound to a Timers::Timer object. To
|
40
|
+
cancel a timer, use `Timers::Timer#cancel`
|
41
|
+
|
42
|
+
Once you've scheduled a timer, you can wait until the next timer fires with `Timers::Group#wait`:
|
43
|
+
|
44
|
+
``` ruby
|
45
|
+
# Waits 5 seconds
|
46
|
+
timers.wait
|
47
|
+
|
48
|
+
# The script will now print "Take five"
|
49
|
+
```
|
50
|
+
|
51
|
+
You can schedule a block to run periodically with `Timers::Group#every`:
|
52
|
+
|
53
|
+
``` ruby
|
54
|
+
every_five_seconds = timers.every(5) { puts "Another 5 seconds" }
|
55
|
+
|
56
|
+
loop { timers.wait }
|
57
|
+
```
|
58
|
+
|
59
|
+
You can also schedule a block to run immediately and periodically with `Timers::Group#now_and_every`:
|
60
|
+
|
61
|
+
``` ruby
|
62
|
+
now_and_every_five_seconds = timers.now_and_every(5) { puts "Now and in another 5 seconds" }
|
63
|
+
|
64
|
+
loop { timers.wait }
|
65
|
+
```
|
66
|
+
|
67
|
+
If you'd like another method to do the waiting for you, e.g. `Kernel.select`,
|
68
|
+
you can use `Timers::Group#wait_interval` to obtain the amount of time to wait. When
|
69
|
+
a timeout is encountered, you can fire all pending timers with `Timers::Group#fire`:
|
70
|
+
|
71
|
+
``` ruby
|
72
|
+
loop do
|
73
|
+
interval = timers.wait_interval
|
74
|
+
ready_readers, ready_writers = select readers, writers, nil, interval
|
75
|
+
|
76
|
+
if ready_readers || ready_writers
|
77
|
+
# Handle IO
|
78
|
+
...
|
79
|
+
else
|
80
|
+
# Timeout!
|
81
|
+
timers.fire
|
82
|
+
end
|
83
|
+
end
|
84
|
+
```
|
85
|
+
|
86
|
+
You can also pause and continue individual timers, or all timers:
|
87
|
+
|
88
|
+
``` ruby
|
89
|
+
paused_timer = timers.every(5) { puts "I was paused" }
|
90
|
+
|
91
|
+
paused_timer.pause
|
92
|
+
10.times { timers.wait } # will not fire paused timer
|
93
|
+
|
94
|
+
paused_timer.resume
|
95
|
+
10.times { timers.wait } # will fire timer
|
96
|
+
|
97
|
+
timers.pause
|
98
|
+
10.times { timers.wait } # will not fire any timers
|
99
|
+
|
100
|
+
timers.resume
|
101
|
+
10.times { timers.wait } # will fire all timers
|
102
|
+
```
|
103
|
+
|
104
|
+
## Contributing
|
105
|
+
|
106
|
+
1. Fork it
|
107
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
108
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
109
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
110
|
+
5. Create new Pull Request
|
data.tar.gz.sig
ADDED
Binary file
|
metadata
CHANGED
@@ -1,15 +1,73 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: timers
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.3.
|
4
|
+
version: 4.3.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
|
-
- Samuel Williams
|
8
7
|
- Tony Arcieri
|
8
|
+
- Samuel Williams
|
9
|
+
- "//de"
|
10
|
+
- Wander Hillen
|
11
|
+
- Jeremy Hinegardner
|
12
|
+
- skinnyjames
|
13
|
+
- Chuck Remes
|
14
|
+
- utenmiki
|
15
|
+
- Olle Jonsson
|
16
|
+
- deadprogrammer
|
17
|
+
- takiy33
|
18
|
+
- Larry Lv
|
19
|
+
- Lin Jen-Shin
|
20
|
+
- Ryunosuke SATO
|
21
|
+
- Tommy Ong Gia Phu
|
22
|
+
- Atul Bhosale
|
23
|
+
- Bruno Enten
|
24
|
+
- Dimitrij Denissenko
|
25
|
+
- Donovan Keme
|
26
|
+
- Feram
|
27
|
+
- Jesse Cooke
|
28
|
+
- Klaus Trainer
|
29
|
+
- Lavir the Whiolet
|
30
|
+
- Mike Bourgeous
|
31
|
+
- Ryan LeCompte
|
32
|
+
- Tim Smith
|
33
|
+
- Vít Ondruch
|
34
|
+
- Will Jessop
|
35
|
+
- Yoshiki Takagi
|
36
|
+
- nicholas a. evans
|
37
|
+
- tommyogp
|
9
38
|
autorequire:
|
10
39
|
bindir: bin
|
11
|
-
cert_chain:
|
12
|
-
|
40
|
+
cert_chain:
|
41
|
+
- |
|
42
|
+
-----BEGIN CERTIFICATE-----
|
43
|
+
MIIE2DCCA0CgAwIBAgIBATANBgkqhkiG9w0BAQsFADBhMRgwFgYDVQQDDA9zYW11
|
44
|
+
ZWwud2lsbGlhbXMxHTAbBgoJkiaJk/IsZAEZFg1vcmlvbnRyYW5zZmVyMRIwEAYK
|
45
|
+
CZImiZPyLGQBGRYCY28xEjAQBgoJkiaJk/IsZAEZFgJuejAeFw0yMjA4MDYwNDUz
|
46
|
+
MjRaFw0zMjA4MDMwNDUzMjRaMGExGDAWBgNVBAMMD3NhbXVlbC53aWxsaWFtczEd
|
47
|
+
MBsGCgmSJomT8ixkARkWDW9yaW9udHJhbnNmZXIxEjAQBgoJkiaJk/IsZAEZFgJj
|
48
|
+
bzESMBAGCgmSJomT8ixkARkWAm56MIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIB
|
49
|
+
igKCAYEAomvSopQXQ24+9DBB6I6jxRI2auu3VVb4nOjmmHq7XWM4u3HL+pni63X2
|
50
|
+
9qZdoq9xt7H+RPbwL28LDpDNflYQXoOhoVhQ37Pjn9YDjl8/4/9xa9+NUpl9XDIW
|
51
|
+
sGkaOY0eqsQm1pEWkHJr3zn/fxoKPZPfaJOglovdxf7dgsHz67Xgd/ka+Wo1YqoE
|
52
|
+
e5AUKRwUuvaUaumAKgPH+4E4oiLXI4T1Ff5Q7xxv6yXvHuYtlMHhYfgNn8iiW8WN
|
53
|
+
XibYXPNP7NtieSQqwR/xM6IRSoyXKuS+ZNGDPUUGk8RoiV/xvVN4LrVm9upSc0ss
|
54
|
+
RZ6qwOQmXCo/lLcDUxJAgG95cPw//sI00tZan75VgsGzSWAOdjQpFM0l4dxvKwHn
|
55
|
+
tUeT3ZsAgt0JnGqNm2Bkz81kG4A2hSyFZTFA8vZGhp+hz+8Q573tAR89y9YJBdYM
|
56
|
+
zp0FM4zwMNEUwgfRzv1tEVVUEXmoFCyhzonUUw4nE4CFu/sE3ffhjKcXcY//qiSW
|
57
|
+
xm4erY3XAgMBAAGjgZowgZcwCQYDVR0TBAIwADALBgNVHQ8EBAMCBLAwHQYDVR0O
|
58
|
+
BBYEFO9t7XWuFf2SKLmuijgqR4sGDlRsMC4GA1UdEQQnMCWBI3NhbXVlbC53aWxs
|
59
|
+
aWFtc0BvcmlvbnRyYW5zZmVyLmNvLm56MC4GA1UdEgQnMCWBI3NhbXVlbC53aWxs
|
60
|
+
aWFtc0BvcmlvbnRyYW5zZmVyLmNvLm56MA0GCSqGSIb3DQEBCwUAA4IBgQB5sxkE
|
61
|
+
cBsSYwK6fYpM+hA5B5yZY2+L0Z+27jF1pWGgbhPH8/FjjBLVn+VFok3CDpRqwXCl
|
62
|
+
xCO40JEkKdznNy2avOMra6PFiQyOE74kCtv7P+Fdc+FhgqI5lMon6tt9rNeXmnW/
|
63
|
+
c1NaMRdxy999hmRGzUSFjozcCwxpy/LwabxtdXwXgSay4mQ32EDjqR1TixS1+smp
|
64
|
+
8C/NCWgpIfzpHGJsjvmH2wAfKtTTqB9CVKLCWEnCHyCaRVuKkrKjqhYCdmMBqCws
|
65
|
+
JkxfQWC+jBVeG9ZtPhQgZpfhvh+6hMhraUYRQ6XGyvBqEUe+yo6DKIT3MtGE2+CP
|
66
|
+
eX9i9ZWBydWb8/rvmwmX2kkcBbX0hZS1rcR593hGc61JR6lvkGYQ2MYskBveyaxt
|
67
|
+
Q2K9NVun/S785AP05vKkXZEFYxqG6EW012U4oLcFl5MySFajYXRYbuUpH6AY+HP8
|
68
|
+
voD0MPg1DssDLKwXyt1eKD/+Fq0bFWhwVM/1XiAXL7lyYUyOq24KHgQ2Csg=
|
69
|
+
-----END CERTIFICATE-----
|
70
|
+
date: 2022-09-02 00:00:00.000000000 Z
|
13
71
|
dependencies:
|
14
72
|
- !ruby/object:Gem::Dependency
|
15
73
|
name: bundler
|
@@ -40,19 +98,47 @@ dependencies:
|
|
40
98
|
- !ruby/object:Gem::Version
|
41
99
|
version: '0'
|
42
100
|
- !ruby/object:Gem::Dependency
|
43
|
-
name:
|
101
|
+
name: bake-test
|
102
|
+
requirement: !ruby/object:Gem::Requirement
|
103
|
+
requirements:
|
104
|
+
- - "~>"
|
105
|
+
- !ruby/object:Gem::Version
|
106
|
+
version: '0.1'
|
107
|
+
type: :development
|
108
|
+
prerelease: false
|
109
|
+
version_requirements: !ruby/object:Gem::Requirement
|
110
|
+
requirements:
|
111
|
+
- - "~>"
|
112
|
+
- !ruby/object:Gem::Version
|
113
|
+
version: '0.1'
|
114
|
+
- !ruby/object:Gem::Dependency
|
115
|
+
name: bake-test-external
|
44
116
|
requirement: !ruby/object:Gem::Requirement
|
45
117
|
requirements:
|
46
118
|
- - "~>"
|
47
119
|
- !ruby/object:Gem::Version
|
48
|
-
version: '
|
120
|
+
version: '0.2'
|
49
121
|
type: :development
|
50
122
|
prerelease: false
|
51
123
|
version_requirements: !ruby/object:Gem::Requirement
|
52
124
|
requirements:
|
53
125
|
- - "~>"
|
54
126
|
- !ruby/object:Gem::Version
|
55
|
-
version: '
|
127
|
+
version: '0.2'
|
128
|
+
- !ruby/object:Gem::Dependency
|
129
|
+
name: sus
|
130
|
+
requirement: !ruby/object:Gem::Requirement
|
131
|
+
requirements:
|
132
|
+
- - "~>"
|
133
|
+
- !ruby/object:Gem::Version
|
134
|
+
version: '0.13'
|
135
|
+
type: :development
|
136
|
+
prerelease: false
|
137
|
+
version_requirements: !ruby/object:Gem::Requirement
|
138
|
+
requirements:
|
139
|
+
- - "~>"
|
140
|
+
- !ruby/object:Gem::Version
|
141
|
+
version: '0.13'
|
56
142
|
description:
|
57
143
|
email:
|
58
144
|
executables: []
|
@@ -63,9 +149,12 @@ files:
|
|
63
149
|
- lib/timers/events.rb
|
64
150
|
- lib/timers/group.rb
|
65
151
|
- lib/timers/interval.rb
|
152
|
+
- lib/timers/priority_heap.rb
|
66
153
|
- lib/timers/timer.rb
|
67
154
|
- lib/timers/version.rb
|
68
155
|
- lib/timers/wait.rb
|
156
|
+
- license.md
|
157
|
+
- readme.md
|
69
158
|
homepage: https://github.com/socketry/timers
|
70
159
|
licenses:
|
71
160
|
- MIT
|
@@ -78,14 +167,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
78
167
|
requirements:
|
79
168
|
- - ">="
|
80
169
|
- !ruby/object:Gem::Version
|
81
|
-
version: '
|
170
|
+
version: '0'
|
82
171
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
83
172
|
requirements:
|
84
173
|
- - ">="
|
85
174
|
- !ruby/object:Gem::Version
|
86
175
|
version: '0'
|
87
176
|
requirements: []
|
88
|
-
rubygems_version: 3.
|
177
|
+
rubygems_version: 3.3.7
|
89
178
|
signing_key:
|
90
179
|
specification_version: 4
|
91
180
|
summary: Pure Ruby one-shot and periodic timers.
|
metadata.gz.sig
ADDED
Binary file
|