timers 2.0.0 → 3.0.0.pre
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/.rspec +2 -1
- data/.travis.yml +3 -2
- data/AUTHORS.md +15 -0
- data/CHANGES.md +6 -0
- data/LICENSE +3 -2
- data/README.md +4 -2
- data/lib/timers.rb +3 -170
- data/lib/timers/group.rb +106 -0
- data/lib/timers/timeout.rb +36 -0
- data/lib/timers/timer.rb +86 -0
- data/lib/timers/version.rb +2 -2
- data/spec/{timers_spec.rb → group_spec.rb} +66 -45
- data/spec/spec_helper.rb +6 -2
- data/spec/timeout_spec.rb +29 -0
- data/timers.gemspec +1 -1
- metadata +17 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3e9bfe42a47fd75ccdb65871da796a7f8fc34c06
|
4
|
+
data.tar.gz: 1b399be03f9c02b444b1564f63694bb41b81ecde
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 61ac36cb1df7d08dc523bd198d3cc510a7d59db6e21a25e7641b9bd3f8d3106518a99ec8691933c2ef64fd5d1abc43e3b2a7f5543baa4ebd7fb09fd5df7f07b0
|
7
|
+
data.tar.gz: c1679de4914d8d11ebccc3e8cc9ab833e9f14ca24ce5cd5bc601b40f5a6dac5cd42268375f15e04e157e8695f0d9ffd26f79c98aec25ac98a6682e7a725555c5
|
data/.rspec
CHANGED
data/.travis.yml
CHANGED
@@ -1,16 +1,17 @@
|
|
1
1
|
rvm:
|
2
2
|
- 1.9.3
|
3
3
|
- 2.0.0
|
4
|
+
- 2.1.2
|
4
5
|
- ruby-head
|
5
6
|
- jruby
|
6
7
|
- jruby-head
|
7
|
-
- rbx
|
8
|
+
- rbx-2
|
8
9
|
|
9
10
|
matrix:
|
10
11
|
allow_failures:
|
11
12
|
- rvm: ruby-head
|
12
13
|
- rvm: jruby-head
|
13
|
-
- rvm: rbx
|
14
|
+
- rvm: rbx-2
|
14
15
|
|
15
16
|
notifications:
|
16
17
|
irc: "irc.freenode.org#celluloid"
|
data/AUTHORS.md
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
# The Celluloid timers gem is beamed directly to you from the minds of...
|
2
|
+
|
3
|
+
- Tony Arcieri <bascule@gmail.com>
|
4
|
+
- Jeremy Hinegardner
|
5
|
+
- Sean Gregory
|
6
|
+
- Chuck Remes
|
7
|
+
- Utenmiki
|
8
|
+
- Ron Evans
|
9
|
+
- Larry Lv
|
10
|
+
- Bruno Enten
|
11
|
+
- Jesse Cooke
|
12
|
+
- Nicholas Evans
|
13
|
+
- Dimitrij Denissenko
|
14
|
+
- Ryan LeCompte
|
15
|
+
- Samuel G. D. Williams
|
data/CHANGES.md
CHANGED
data/LICENSE
CHANGED
@@ -1,4 +1,5 @@
|
|
1
|
-
Copyright (c) 2012
|
1
|
+
Copyright (c) 2012-14 The Celluloid Timers Developers: given in the file
|
2
|
+
AUTHORS.md at https://github.com/celluloid/timers/blob/master/AUTHORS.md
|
2
3
|
|
3
4
|
MIT License
|
4
5
|
|
@@ -19,4 +20,4 @@ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
19
20
|
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
21
|
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
22
|
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
-
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
23
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
CHANGED
@@ -90,5 +90,7 @@ timers.continue
|
|
90
90
|
License
|
91
91
|
-------
|
92
92
|
|
93
|
-
Copyright (c)
|
94
|
-
|
93
|
+
Copyright (c) 2014 Celluloid timers project developers (given in the file
|
94
|
+
AUTHORS.md).
|
95
|
+
|
96
|
+
Distributed under the MIT License. See LICENSE file for further details.
|
data/lib/timers.rb
CHANGED
@@ -1,176 +1,9 @@
|
|
1
|
-
require 'set'
|
2
|
-
require 'forwardable'
|
3
|
-
require 'timers/version'
|
4
|
-
require 'hitimes'
|
5
1
|
|
6
2
|
# Workaround for thread safety issues in SortedSet initialization
|
7
3
|
# See: https://github.com/celluloid/timers/issues/20
|
8
4
|
SortedSet.new
|
9
5
|
|
10
|
-
|
11
|
-
include Enumerable
|
12
|
-
extend Forwardable
|
13
|
-
def_delegators :@timers, :delete, :each, :empty?
|
14
|
-
|
15
|
-
def initialize
|
16
|
-
@timers = SortedSet.new
|
17
|
-
@paused_timers = SortedSet.new
|
18
|
-
@interval = Hitimes::Interval.new
|
19
|
-
@interval.start
|
20
|
-
end
|
21
|
-
|
22
|
-
# Call the given block after the given interval
|
23
|
-
def after(interval, &block)
|
24
|
-
Timer.new(self, interval, false, &block)
|
25
|
-
end
|
26
|
-
|
27
|
-
# Call the given block after the given interval has expired. +interval+
|
28
|
-
# is measured in milliseconds.
|
29
|
-
#
|
30
|
-
# Timer.new.after_milliseconds(25) { puts "fired!" }
|
31
|
-
#
|
32
|
-
def after_milliseconds(interval, &block)
|
33
|
-
after(interval / 1000.0, &block)
|
34
|
-
end
|
35
|
-
alias_method :after_ms, :after_milliseconds
|
36
|
-
|
37
|
-
# Call the given block periodically at the given interval
|
38
|
-
def every(interval, &block)
|
39
|
-
Timer.new(self, interval, true, &block)
|
40
|
-
end
|
41
|
-
|
42
|
-
# Wait for the next timer and fire it
|
43
|
-
def wait
|
44
|
-
i = wait_interval
|
45
|
-
sleep i if i
|
46
|
-
fire
|
47
|
-
end
|
48
|
-
|
49
|
-
# Interval to wait until when the next timer will fire
|
50
|
-
def wait_interval(offset = self.current_offset)
|
51
|
-
timer = @timers.first
|
52
|
-
return unless timer
|
53
|
-
interval = timer.offset - Float(offset)
|
54
|
-
interval > 0 ? interval : 0
|
55
|
-
end
|
56
|
-
|
57
|
-
# Fire all timers that are ready
|
58
|
-
def fire(offset = self.current_offset)
|
59
|
-
time = Float(offset) + 0.001 # Fudge 1ms in case of clock imprecision
|
60
|
-
while (timer = @timers.first) && (time >= timer.offset)
|
61
|
-
@timers.delete timer
|
62
|
-
timer.fire(offset)
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
|
-
def add(timer)
|
67
|
-
raise TypeError, "not a Timers::Timer" unless timer.is_a? Timers::Timer
|
68
|
-
@timers.add(timer)
|
69
|
-
end
|
70
|
-
|
71
|
-
def pause(timer = nil)
|
72
|
-
return pause_all if timer.nil?
|
73
|
-
raise TypeError, "not a Timers::Timer" unless timer.is_a? Timers::Timer
|
74
|
-
@timers.delete timer
|
75
|
-
@paused_timers.add timer
|
76
|
-
end
|
77
|
-
|
78
|
-
def pause_all
|
79
|
-
@timers.each {|timer| timer.pause}
|
80
|
-
end
|
81
|
-
|
82
|
-
def continue(timer = nil)
|
83
|
-
return continue_all if timer.nil?
|
84
|
-
raise TypeError, "not a Timers::Timer" unless timer.is_a? Timers::Timer
|
85
|
-
@paused_timers.delete timer
|
86
|
-
@timers.add timer
|
87
|
-
end
|
88
|
-
|
89
|
-
def continue_all
|
90
|
-
@paused_timers.each {|timer| timer.continue}
|
91
|
-
end
|
92
|
-
|
93
|
-
def delay(seconds)
|
94
|
-
@timers.each {|timer| timer.delay(seconds)}
|
95
|
-
end
|
96
|
-
|
97
|
-
alias_method :cancel, :delete
|
98
|
-
|
99
|
-
def current_offset
|
100
|
-
@interval.to_f
|
101
|
-
end
|
102
|
-
|
103
|
-
# An individual timer set to fire a given proc at a given time
|
104
|
-
class Timer
|
105
|
-
include Comparable
|
106
|
-
attr_reader :interval, :offset, :recurring
|
107
|
-
|
108
|
-
def initialize(timers, interval, recurring = false, &block)
|
109
|
-
@timers, @interval, @recurring = timers, interval, recurring
|
110
|
-
@block = block
|
111
|
-
@offset = nil
|
112
|
-
|
113
|
-
reset
|
114
|
-
end
|
115
|
-
|
116
|
-
def <=>(other)
|
117
|
-
@offset <=> other.offset
|
118
|
-
end
|
119
|
-
|
120
|
-
# Cancel this timer
|
121
|
-
def cancel
|
122
|
-
@timers.cancel self
|
123
|
-
end
|
124
|
-
|
125
|
-
# Extend this timer
|
126
|
-
def delay(seconds)
|
127
|
-
@timers.delete self
|
128
|
-
@offset += seconds
|
129
|
-
@timers.add self
|
130
|
-
end
|
131
|
-
|
132
|
-
# Reset this timer
|
133
|
-
def reset(offset = @timers.current_offset)
|
134
|
-
@timers.cancel self if @time
|
135
|
-
@offset = Float(offset) + @interval
|
136
|
-
@timers.add self
|
137
|
-
end
|
138
|
-
|
139
|
-
# Fire the block
|
140
|
-
def fire(offset = @timers.current_offset)
|
141
|
-
reset(offset) if recurring
|
142
|
-
@block.call
|
143
|
-
end
|
144
|
-
alias_method :call, :fire
|
145
|
-
|
146
|
-
# Pause this timer
|
147
|
-
def pause
|
148
|
-
@timers.pause self
|
149
|
-
end
|
150
|
-
|
151
|
-
# Continue this timer
|
152
|
-
def continue
|
153
|
-
@timers.continue self
|
154
|
-
end
|
155
|
-
|
156
|
-
# Inspect a timer
|
157
|
-
def inspect
|
158
|
-
str = "#<Timers::Timer:#{object_id.to_s(16)} "
|
159
|
-
offset = @timers.current_offset
|
160
|
-
|
161
|
-
if @offset
|
162
|
-
if @offset >= offset
|
163
|
-
str << "fires in #{@offset - offset} seconds"
|
164
|
-
else
|
165
|
-
str << "fired #{offset - @offset} seconds ago"
|
166
|
-
end
|
167
|
-
|
168
|
-
str << ", recurs every #{interval}" if recurring
|
169
|
-
else
|
170
|
-
str << "dead"
|
171
|
-
end
|
6
|
+
require 'timers/version'
|
172
7
|
|
173
|
-
|
174
|
-
|
175
|
-
end
|
176
|
-
end
|
8
|
+
require 'timers/group'
|
9
|
+
require 'timers/timeout'
|
data/lib/timers/group.rb
ADDED
@@ -0,0 +1,106 @@
|
|
1
|
+
|
2
|
+
require 'set'
|
3
|
+
require 'forwardable'
|
4
|
+
require 'hitimes'
|
5
|
+
|
6
|
+
require 'timers/timer'
|
7
|
+
|
8
|
+
module Timers
|
9
|
+
class Group
|
10
|
+
include Enumerable
|
11
|
+
extend Forwardable
|
12
|
+
def_delegators :@timers, :delete, :each, :empty?
|
13
|
+
|
14
|
+
def initialize
|
15
|
+
@timers = SortedSet.new
|
16
|
+
@paused_timers = SortedSet.new
|
17
|
+
@interval = Hitimes::Interval.new
|
18
|
+
@interval.start
|
19
|
+
end
|
20
|
+
|
21
|
+
# Call the given block after the given interval
|
22
|
+
def after(interval, &block)
|
23
|
+
Timer.new(self, interval, false, &block)
|
24
|
+
end
|
25
|
+
|
26
|
+
# Call the given block after the given interval has expired. +interval+
|
27
|
+
# is measured in milliseconds.
|
28
|
+
#
|
29
|
+
# Timer.new.after_milliseconds(25) { puts "fired!" }
|
30
|
+
#
|
31
|
+
def after_milliseconds(interval, &block)
|
32
|
+
after(interval / 1000.0, &block)
|
33
|
+
end
|
34
|
+
alias_method :after_ms, :after_milliseconds
|
35
|
+
|
36
|
+
# Call the given block periodically at the given interval
|
37
|
+
def every(interval, &block)
|
38
|
+
Timer.new(self, interval, true, &block)
|
39
|
+
end
|
40
|
+
|
41
|
+
# Wait for the next timer and fire it
|
42
|
+
def wait
|
43
|
+
# Repeatedly call sleep until there is no longer any wait_interval:
|
44
|
+
while i = wait_interval
|
45
|
+
# We cannot assume that sleep will wait for the specified time, it might be +/- a bit.
|
46
|
+
sleep i
|
47
|
+
end
|
48
|
+
|
49
|
+
fire
|
50
|
+
end
|
51
|
+
|
52
|
+
# Interval to wait until when the next timer will fire
|
53
|
+
def wait_interval(offset = self.current_offset)
|
54
|
+
timer = @timers.first
|
55
|
+
return unless timer
|
56
|
+
interval = timer.offset - Float(offset)
|
57
|
+
interval > 0 ? interval : nil
|
58
|
+
end
|
59
|
+
|
60
|
+
# Fire all timers that are ready
|
61
|
+
def fire(offset = self.current_offset)
|
62
|
+
time = Float(offset)
|
63
|
+
while (timer = @timers.first) && (time >= timer.offset)
|
64
|
+
@timers.delete timer
|
65
|
+
timer.fire(offset)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def add(timer)
|
70
|
+
raise TypeError, "not a Timers::Timer" unless timer.is_a? Timers::Timer
|
71
|
+
@timers.add(timer)
|
72
|
+
end
|
73
|
+
|
74
|
+
def pause(timer = nil)
|
75
|
+
return pause_all if timer.nil?
|
76
|
+
raise TypeError, "not a Timers::Timer" unless timer.is_a? Timers::Timer
|
77
|
+
@timers.delete timer
|
78
|
+
@paused_timers.add timer
|
79
|
+
end
|
80
|
+
|
81
|
+
def pause_all
|
82
|
+
@timers.each {|timer| timer.pause}
|
83
|
+
end
|
84
|
+
|
85
|
+
def continue(timer = nil)
|
86
|
+
return continue_all if timer.nil?
|
87
|
+
raise TypeError, "not a Timers::Timer" unless timer.is_a? Timers::Timer
|
88
|
+
@paused_timers.delete timer
|
89
|
+
@timers.add timer
|
90
|
+
end
|
91
|
+
|
92
|
+
def continue_all
|
93
|
+
@paused_timers.each {|timer| timer.continue}
|
94
|
+
end
|
95
|
+
|
96
|
+
def delay(seconds)
|
97
|
+
@timers.each {|timer| timer.delay(seconds)}
|
98
|
+
end
|
99
|
+
|
100
|
+
alias_method :cancel, :delete
|
101
|
+
|
102
|
+
def current_offset
|
103
|
+
@interval.to_f
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
|
2
|
+
require 'hitimes'
|
3
|
+
|
4
|
+
module Timers
|
5
|
+
# An exclusive, monotonic timeout class.
|
6
|
+
class Timeout
|
7
|
+
def initialize(duration)
|
8
|
+
@duration = duration
|
9
|
+
@remaining = true
|
10
|
+
end
|
11
|
+
|
12
|
+
attr :duration
|
13
|
+
attr :remaining
|
14
|
+
|
15
|
+
# Yields while time remains for work to be done:
|
16
|
+
def while_time_remaining(&block)
|
17
|
+
@interval = Hitimes::Interval.new
|
18
|
+
@interval.start
|
19
|
+
|
20
|
+
while time_remaining?
|
21
|
+
yield @remaining
|
22
|
+
end
|
23
|
+
ensure
|
24
|
+
@interval.stop
|
25
|
+
@interval = nil
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def time_remaining?
|
31
|
+
@remaining = (@duration - @interval.duration)
|
32
|
+
|
33
|
+
return @remaining > 0
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
data/lib/timers/timer.rb
ADDED
@@ -0,0 +1,86 @@
|
|
1
|
+
|
2
|
+
module Timers
|
3
|
+
# An individual timer set to fire a given proc at a given time
|
4
|
+
class Timer
|
5
|
+
include Comparable
|
6
|
+
attr_reader :interval, :offset, :recurring
|
7
|
+
|
8
|
+
def initialize(timers, interval, recurring = false, &block)
|
9
|
+
@timers, @interval, @recurring = timers, interval, recurring
|
10
|
+
@block = block
|
11
|
+
@offset = nil
|
12
|
+
|
13
|
+
reset
|
14
|
+
end
|
15
|
+
|
16
|
+
def <=>(other)
|
17
|
+
@offset <=> other.offset
|
18
|
+
end
|
19
|
+
|
20
|
+
# Cancel this timer
|
21
|
+
def cancel
|
22
|
+
@timers.cancel self
|
23
|
+
end
|
24
|
+
|
25
|
+
# Extend this timer
|
26
|
+
def delay(seconds)
|
27
|
+
@timers.delete self
|
28
|
+
@offset += seconds
|
29
|
+
@timers.add self
|
30
|
+
end
|
31
|
+
|
32
|
+
# Reset this timer
|
33
|
+
def reset(offset = @timers.current_offset)
|
34
|
+
@timers.cancel self if @offset
|
35
|
+
@offset = Float(offset) + @interval
|
36
|
+
@timers.add self
|
37
|
+
end
|
38
|
+
|
39
|
+
# Fire the block
|
40
|
+
def fire(offset = @timers.current_offset)
|
41
|
+
if recurring
|
42
|
+
reset(offset)
|
43
|
+
else
|
44
|
+
@offset = offset
|
45
|
+
end
|
46
|
+
|
47
|
+
@block.call
|
48
|
+
end
|
49
|
+
alias_method :call, :fire
|
50
|
+
|
51
|
+
# Pause this timer
|
52
|
+
def pause
|
53
|
+
@timers.pause self
|
54
|
+
end
|
55
|
+
|
56
|
+
# Continue this timer
|
57
|
+
def continue
|
58
|
+
@timers.continue self
|
59
|
+
end
|
60
|
+
|
61
|
+
# Number of seconds until next fire / since last fire
|
62
|
+
def fires_in
|
63
|
+
@offset - @timers.current_offset if @offset
|
64
|
+
end
|
65
|
+
|
66
|
+
# Inspect a timer
|
67
|
+
def inspect
|
68
|
+
str = "#<Timers::Timer:#{object_id.to_s(16)} "
|
69
|
+
offset = @timers.current_offset
|
70
|
+
|
71
|
+
if @offset
|
72
|
+
if fires_in >= 0
|
73
|
+
str << "fires in #{fires_in} seconds"
|
74
|
+
else
|
75
|
+
str << "fired #{fires_in.abs} seconds ago"
|
76
|
+
end
|
77
|
+
|
78
|
+
str << ", recurs every #{interval}" if recurring
|
79
|
+
else
|
80
|
+
str << "dead"
|
81
|
+
end
|
82
|
+
|
83
|
+
str << ">"
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
data/lib/timers/version.rb
CHANGED
@@ -1,3 +1,3 @@
|
|
1
|
-
|
2
|
-
VERSION = "
|
1
|
+
module Timers
|
2
|
+
VERSION = "3.0.0.pre"
|
3
3
|
end
|
@@ -1,48 +1,46 @@
|
|
1
|
-
require 'spec_helper'
|
2
1
|
|
3
|
-
|
4
|
-
# Level of accuracy enforced by tests (50ms)
|
5
|
-
Q = 0.05
|
2
|
+
require 'spec_helper'
|
6
3
|
|
4
|
+
describe Timers::Group do
|
7
5
|
it "sleeps until the next timer" do
|
8
|
-
interval =
|
6
|
+
interval = TIMER_QUANTUM * 2
|
9
7
|
started_at = Time.now
|
10
8
|
|
11
9
|
fired = false
|
12
10
|
subject.after(interval) { fired = true }
|
13
11
|
subject.wait
|
14
12
|
|
15
|
-
expect(fired).to
|
16
|
-
expect(Time.now - started_at).to be_within(
|
13
|
+
expect(fired).to be true
|
14
|
+
expect(Time.now - started_at).to be_within(TIMER_QUANTUM).of interval
|
17
15
|
end
|
18
16
|
|
19
17
|
it "fires instantly when next timer is in the past" do
|
20
18
|
fired = false
|
21
|
-
subject.after(
|
22
|
-
sleep(
|
19
|
+
subject.after(TIMER_QUANTUM) { fired = true }
|
20
|
+
sleep(TIMER_QUANTUM * 2)
|
23
21
|
subject.wait
|
24
22
|
|
25
|
-
expect(fired).to
|
23
|
+
expect(fired).to be true
|
26
24
|
end
|
27
25
|
|
28
26
|
it "calculates the interval until the next timer should fire" do
|
29
27
|
interval = 0.1
|
30
28
|
|
31
29
|
subject.after(interval)
|
32
|
-
expect(subject.wait_interval).to be_within(
|
30
|
+
expect(subject.wait_interval).to be_within(TIMER_QUANTUM).of interval
|
33
31
|
|
34
32
|
sleep(interval)
|
35
|
-
expect(subject.wait_interval).to be(
|
33
|
+
expect(subject.wait_interval).to be(nil)
|
36
34
|
end
|
37
35
|
|
38
36
|
it "fires timers in the correct order" do
|
39
37
|
result = []
|
40
38
|
|
41
|
-
subject.after(
|
42
|
-
subject.after(
|
43
|
-
subject.after(
|
39
|
+
subject.after(TIMER_QUANTUM * 2) { result << :two }
|
40
|
+
subject.after(TIMER_QUANTUM * 3) { result << :three }
|
41
|
+
subject.after(TIMER_QUANTUM * 1) { result << :one }
|
44
42
|
|
45
|
-
sleep
|
43
|
+
sleep TIMER_QUANTUM * 4
|
46
44
|
subject.fire
|
47
45
|
|
48
46
|
expect(result).to eq [:one, :two, :three]
|
@@ -58,13 +56,13 @@ describe Timers do
|
|
58
56
|
it "continues to fire the timers at each interval" do
|
59
57
|
result = []
|
60
58
|
|
61
|
-
subject.every(
|
59
|
+
subject.every(TIMER_QUANTUM * 2) { result << :foo }
|
62
60
|
|
63
|
-
sleep
|
61
|
+
sleep TIMER_QUANTUM * 3
|
64
62
|
subject.fire
|
65
63
|
expect(result).to eq [:foo]
|
66
64
|
|
67
|
-
sleep
|
65
|
+
sleep TIMER_QUANTUM * 5
|
68
66
|
subject.fire
|
69
67
|
expect(result).to eq [:foo, :foo]
|
70
68
|
end
|
@@ -77,13 +75,13 @@ describe Timers do
|
|
77
75
|
subject.after_milliseconds(interval_ms)
|
78
76
|
expected_elapse = subject.wait_interval
|
79
77
|
|
80
|
-
expect(subject.wait_interval).to be_within(
|
78
|
+
expect(subject.wait_interval).to be_within(TIMER_QUANTUM).of(interval_ms / 1000.0)
|
81
79
|
end
|
82
80
|
end
|
83
81
|
|
84
82
|
describe "pause and continue timers" do
|
85
83
|
before(:each) do
|
86
|
-
@interval =
|
84
|
+
@interval = TIMER_QUANTUM * 2
|
87
85
|
started_at = Time.now
|
88
86
|
|
89
87
|
@fired = false
|
@@ -95,7 +93,7 @@ describe Timers do
|
|
95
93
|
it "does not fire when paused" do
|
96
94
|
@timer.pause
|
97
95
|
subject.wait
|
98
|
-
expect(@fired).to
|
96
|
+
expect(@fired).to be false
|
99
97
|
end
|
100
98
|
|
101
99
|
it "fires when continued after pause" do
|
@@ -103,14 +101,14 @@ describe Timers do
|
|
103
101
|
subject.wait
|
104
102
|
@timer.continue
|
105
103
|
subject.wait
|
106
|
-
expect(@fired).to
|
104
|
+
expect(@fired).to be true
|
107
105
|
end
|
108
106
|
|
109
107
|
it "can pause all timers at once" do
|
110
108
|
subject.pause
|
111
109
|
subject.wait
|
112
|
-
expect(@fired).to
|
113
|
-
expect(@fired2).to
|
110
|
+
expect(@fired).to be false
|
111
|
+
expect(@fired2).to be false
|
114
112
|
end
|
115
113
|
|
116
114
|
it "can continue all timers at once" do
|
@@ -118,20 +116,20 @@ describe Timers do
|
|
118
116
|
subject.wait
|
119
117
|
subject.continue
|
120
118
|
subject.wait
|
121
|
-
expect(@fired).to
|
122
|
-
expect(@fired2).to
|
119
|
+
expect(@fired).to be true
|
120
|
+
expect(@fired2).to be true
|
123
121
|
end
|
124
122
|
|
125
123
|
it "can fire the timer directly" do
|
126
124
|
fired = false
|
127
|
-
timer = subject.after(
|
125
|
+
timer = subject.after( TIMER_QUANTUM * 1 ) { fired = true }
|
128
126
|
timer.pause
|
129
127
|
subject.wait
|
130
|
-
expect(fired).not_to
|
128
|
+
expect(fired).not_to be true
|
131
129
|
timer.continue
|
132
|
-
expect(fired).not_to
|
130
|
+
expect(fired).not_to be true
|
133
131
|
timer.fire
|
134
|
-
expect(fired).to
|
132
|
+
expect(fired).to be true
|
135
133
|
end
|
136
134
|
|
137
135
|
end
|
@@ -140,7 +138,7 @@ describe Timers do
|
|
140
138
|
it "adds appropriate amount of time to timer" do
|
141
139
|
timer = subject.after(10)
|
142
140
|
timer.delay(5)
|
143
|
-
expect(timer.offset - subject.current_offset).to be_within(
|
141
|
+
expect(timer.offset - subject.current_offset).to be_within(TIMER_QUANTUM).of(15)
|
144
142
|
end
|
145
143
|
end
|
146
144
|
|
@@ -149,8 +147,8 @@ describe Timers do
|
|
149
147
|
timer = subject.after(10)
|
150
148
|
timer2 = subject.after(20)
|
151
149
|
subject.delay(5)
|
152
|
-
expect(timer.offset - subject.current_offset).to be_within(
|
153
|
-
expect(timer2.offset - subject.current_offset).to be_within(
|
150
|
+
expect(timer.offset - subject.current_offset).to be_within(TIMER_QUANTUM).of(15)
|
151
|
+
expect(timer2.offset - subject.current_offset).to be_within(TIMER_QUANTUM).of(25)
|
154
152
|
end
|
155
153
|
end
|
156
154
|
|
@@ -158,12 +156,12 @@ describe Timers do
|
|
158
156
|
it "fires timers in the correct order" do
|
159
157
|
result = []
|
160
158
|
|
161
|
-
second = subject.after(
|
162
|
-
third = subject.after(
|
163
|
-
first = subject.after(
|
164
|
-
first.delay(
|
159
|
+
second = subject.after(TIMER_QUANTUM * 2) { result << :two }
|
160
|
+
third = subject.after(TIMER_QUANTUM * 3) { result << :three }
|
161
|
+
first = subject.after(TIMER_QUANTUM * 1) { result << :one }
|
162
|
+
first.delay(TIMER_QUANTUM * 3)
|
165
163
|
|
166
|
-
sleep
|
164
|
+
sleep TIMER_QUANTUM * 5
|
167
165
|
subject.fire
|
168
166
|
|
169
167
|
expect(result).to eq [:two, :three, :one]
|
@@ -173,29 +171,52 @@ describe Timers do
|
|
173
171
|
describe "Timer inspection" do
|
174
172
|
it "before firing" do
|
175
173
|
fired = false
|
176
|
-
timer = subject.after(
|
174
|
+
timer = subject.after(TIMER_QUANTUM * 5) { fired = true }
|
177
175
|
timer.pause
|
178
|
-
expect(fired).not_to
|
176
|
+
expect(fired).not_to be true
|
179
177
|
expect(timer.inspect).to match(/\A#<Timers::Timer:[\da-f]+ fires in [-\.\de]+ seconds>\Z/)
|
180
178
|
end
|
181
179
|
|
182
180
|
it "after firing" do
|
183
181
|
fired = false
|
184
|
-
timer = subject.after(
|
182
|
+
timer = subject.after(TIMER_QUANTUM) { fired = true }
|
185
183
|
|
186
184
|
subject.wait
|
187
185
|
|
188
|
-
expect(fired).to
|
186
|
+
expect(fired).to be true
|
189
187
|
expect(timer.inspect).to match(/\A#<Timers::Timer:[\da-f]+ fired [-\.\de]+ seconds ago>\Z/)
|
190
188
|
end
|
191
189
|
|
192
190
|
it "recurring firing" do
|
193
191
|
result = []
|
194
|
-
timer = subject.every(
|
192
|
+
timer = subject.every(TIMER_QUANTUM) { result << :foo }
|
195
193
|
|
196
194
|
subject.wait
|
197
195
|
expect(result).not_to be_empty
|
198
|
-
expect(timer.inspect).to match(/\A#<Timers::Timer:[\da-f]+ fires in [-\.\de]+ seconds, recurs every #{sprintf("%0.2f",
|
196
|
+
expect(timer.inspect).to match(/\A#<Timers::Timer:[\da-f]+ fires in [-\.\de]+ seconds, recurs every #{sprintf("%0.2f", TIMER_QUANTUM)}>\Z/)
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
200
|
+
describe "fires_in" do
|
201
|
+
let(:interval) { TIMER_QUANTUM * 2 }
|
202
|
+
|
203
|
+
it "calculates the interval until the next fire if it's recurring" do
|
204
|
+
timer = subject.every(interval) { true }
|
205
|
+
expect(timer.fires_in).to be_within(TIMER_QUANTUM).of(interval)
|
206
|
+
end
|
207
|
+
|
208
|
+
context "when timer is not recurring" do
|
209
|
+
let!(:timer) { subject.after(interval) { true } }
|
210
|
+
|
211
|
+
it "calculates the interval until the next fire if it hasn't already fired" do
|
212
|
+
expect(timer.fires_in).to be_within(TIMER_QUANTUM).of(interval)
|
213
|
+
end
|
214
|
+
|
215
|
+
it "calculates the interval since last fire if already fired" do
|
216
|
+
subject.wait
|
217
|
+
sleep(interval)
|
218
|
+
expect(timer.fires_in).to be_within(TIMER_QUANTUM).of(0 - interval)
|
219
|
+
end
|
199
220
|
end
|
200
221
|
end
|
201
222
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -0,0 +1,29 @@
|
|
1
|
+
|
2
|
+
require 'spec_helper'
|
3
|
+
require 'timers/timeout'
|
4
|
+
|
5
|
+
describe Timers::Timeout do
|
6
|
+
it "repeats until timeout expired" do
|
7
|
+
timeout = Timers::Timeout.new(5)
|
8
|
+
count = 0
|
9
|
+
|
10
|
+
timeout.while_time_remaining do |remaining|
|
11
|
+
expect(remaining).to be_within(TIMER_QUANTUM).of (timeout.duration - count)
|
12
|
+
|
13
|
+
count += 1
|
14
|
+
sleep 1
|
15
|
+
end
|
16
|
+
|
17
|
+
expect(count).to eq(5)
|
18
|
+
end
|
19
|
+
|
20
|
+
it "yields results as soon as possible" do
|
21
|
+
timeout = Timers::Timeout.new(5)
|
22
|
+
|
23
|
+
result = timeout.while_time_remaining do |remaining|
|
24
|
+
break :done
|
25
|
+
end
|
26
|
+
|
27
|
+
expect(result).to eq(:done)
|
28
|
+
end
|
29
|
+
end
|
data/timers.gemspec
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: timers
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 3.0.0.pre
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tony Arcieri
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2014-06-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: hitimes
|
@@ -42,16 +42,16 @@ dependencies:
|
|
42
42
|
name: rspec
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- - "
|
45
|
+
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version:
|
47
|
+
version: 3.0.0
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
|
-
- - "
|
52
|
+
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version:
|
54
|
+
version: 3.0.0
|
55
55
|
description: Pure Ruby one-shot and periodic timers
|
56
56
|
email:
|
57
57
|
- tony.arcieri@gmail.com
|
@@ -63,15 +63,20 @@ files:
|
|
63
63
|
- ".gitignore"
|
64
64
|
- ".rspec"
|
65
65
|
- ".travis.yml"
|
66
|
+
- AUTHORS.md
|
66
67
|
- CHANGES.md
|
67
68
|
- Gemfile
|
68
69
|
- LICENSE
|
69
70
|
- README.md
|
70
71
|
- Rakefile
|
71
72
|
- lib/timers.rb
|
73
|
+
- lib/timers/group.rb
|
74
|
+
- lib/timers/timeout.rb
|
75
|
+
- lib/timers/timer.rb
|
72
76
|
- lib/timers/version.rb
|
77
|
+
- spec/group_spec.rb
|
73
78
|
- spec/spec_helper.rb
|
74
|
-
- spec/
|
79
|
+
- spec/timeout_spec.rb
|
75
80
|
- timers.gemspec
|
76
81
|
homepage: https://github.com/celluloid/timers
|
77
82
|
licenses:
|
@@ -88,16 +93,17 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
88
93
|
version: '0'
|
89
94
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
90
95
|
requirements:
|
91
|
-
- - "
|
96
|
+
- - ">"
|
92
97
|
- !ruby/object:Gem::Version
|
93
|
-
version:
|
98
|
+
version: 1.3.1
|
94
99
|
requirements: []
|
95
100
|
rubyforge_project:
|
96
|
-
rubygems_version: 2.2.
|
101
|
+
rubygems_version: 2.2.2
|
97
102
|
signing_key:
|
98
103
|
specification_version: 4
|
99
104
|
summary: Schedule procs to run after a certain time, or at periodic intervals, using
|
100
105
|
any API that accepts a timeout
|
101
106
|
test_files:
|
107
|
+
- spec/group_spec.rb
|
102
108
|
- spec/spec_helper.rb
|
103
|
-
- spec/
|
109
|
+
- spec/timeout_spec.rb
|