timers 4.1.1 → 4.3.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,57 +0,0 @@
1
-
2
- require 'spec_helper'
3
-
4
- RSpec.describe Timers::Events do
5
- it "should register an event" do
6
- fired = false
7
-
8
- callback = proc do |time|
9
- fired = true
10
- end
11
-
12
- subject.schedule(0.1, callback)
13
-
14
- expect(subject.size).to be == 1
15
-
16
- subject.fire(0.15)
17
-
18
- expect(subject.size).to be == 0
19
-
20
- expect(fired).to be true
21
- end
22
-
23
- it "should register events in order" do
24
- fired = []
25
-
26
- times = [0.95, 0.1, 0.3, 0.5, 0.4, 0.2, 0.01, 0.9]
27
-
28
- times.each do |requested_time|
29
- callback = proc do |time|
30
- fired << requested_time
31
- end
32
-
33
- subject.schedule(requested_time, callback)
34
- end
35
-
36
- subject.fire(0.5)
37
- expect(fired).to be == times.sort.first(6)
38
-
39
- subject.fire(1.0)
40
- expect(fired).to be == times.sort
41
- end
42
-
43
- it "should fire events with the time they were fired at" do
44
- fired_at = :not_fired
45
-
46
- callback = proc do |time|
47
- # The time we actually were fired at:
48
- fired_at = time
49
- end
50
-
51
- subject.schedule(0.5, callback)
52
-
53
- subject.fire(1.0)
54
-
55
- expect(fired_at).to be == 1.0
56
- end
57
- end
@@ -1,34 +0,0 @@
1
-
2
- require 'spec_helper'
3
-
4
- RSpec.describe Timers::Group do
5
- it "should fire several times" do
6
- result = []
7
-
8
- subject.every(0.7) { result << :a }
9
- subject.every(2.3) { result << :b }
10
- subject.every(1.3) { result << :c }
11
- subject.every(2.4) { result << :d }
12
-
13
- Timers::Wait.for(2.5) do |remaining|
14
- subject.wait if subject.wait_interval < remaining
15
- end
16
-
17
- expect(result).to be == [:a, :c, :a, :a, :b, :d]
18
- end
19
-
20
- it "should fire immediately and then several times later" do
21
- result = []
22
-
23
- subject.every(0.7) { result << :a }
24
- subject.every(2.3) { result << :b }
25
- subject.now_and_every(1.3) { result << :c }
26
- subject.now_and_every(2.4) { result << :d }
27
-
28
- Timers::Wait.for(2.5) do |remaining|
29
- subject.wait if subject.wait_interval < remaining
30
- end
31
-
32
- expect(result).to be == [:c, :d, :a, :c, :a, :a, :b, :d]
33
- end
34
- end
@@ -1,254 +0,0 @@
1
-
2
- require 'spec_helper'
3
-
4
- RSpec.describe Timers::Group do
5
- describe "#wait" do
6
- it "calls the wait block with nil" do
7
- called = false
8
-
9
- subject.wait do |interval|
10
- expect(interval).to be == nil
11
- called = true
12
- end
13
-
14
- expect(called).to be true
15
- end
16
-
17
- it "calls the wait block with an interval" do
18
- called = false
19
- fired = false
20
-
21
- subject.after(0.1) { fired = true }
22
-
23
- subject.wait do |interval|
24
- expect(interval).to be_within(TIMER_QUANTUM).of(0.1)
25
- called = true
26
- sleep 0.2
27
- end
28
-
29
- expect(called).to be true
30
- expect(fired).to be true
31
- end
32
- end
33
-
34
- it "sleeps until the next timer" do
35
- interval = TIMER_QUANTUM * 2
36
- started_at = Time.now
37
-
38
- fired = false
39
- subject.after(interval) { fired = true }
40
- subject.wait
41
-
42
- expect(fired).to be true
43
- expect(Time.now - started_at).to be_within(TIMER_QUANTUM).of interval
44
- end
45
-
46
- it "fires instantly when next timer is in the past" do
47
- fired = false
48
- subject.after(TIMER_QUANTUM) { fired = true }
49
- sleep(TIMER_QUANTUM * 2)
50
- subject.wait
51
-
52
- expect(fired).to be true
53
- end
54
-
55
- it "calculates the interval until the next timer should fire" do
56
- interval = 0.1
57
-
58
- subject.after(interval)
59
- expect(subject.wait_interval).to be_within(TIMER_QUANTUM).of interval
60
-
61
- sleep(interval)
62
- expect(subject.wait_interval).to be <= 0
63
- end
64
-
65
- it "fires timers in the correct order" do
66
- result = []
67
-
68
- subject.after(TIMER_QUANTUM * 2) { result << :two }
69
- subject.after(TIMER_QUANTUM * 3) { result << :three }
70
- subject.after(TIMER_QUANTUM * 1) { result << :one }
71
-
72
- sleep TIMER_QUANTUM * 4
73
- subject.fire
74
-
75
- expect(result).to eq [:one, :two, :three]
76
- end
77
-
78
- it "raises TypeError if given an invalid time" do
79
- expect do
80
- subject.after(nil) { nil }
81
- end.to raise_exception(TypeError)
82
- end
83
-
84
- describe "recurring timers" do
85
- it "continues to fire the timers at each interval" do
86
- result = []
87
-
88
- subject.every(TIMER_QUANTUM * 2) { result << :foo }
89
-
90
- sleep TIMER_QUANTUM * 3
91
- subject.fire
92
- expect(result).to eq [:foo]
93
-
94
- sleep TIMER_QUANTUM * 5
95
- subject.fire
96
- expect(result).to eq [:foo, :foo]
97
- end
98
- end
99
-
100
- it "calculates the proper interval to wait until firing" do
101
- interval_ms = 25
102
-
103
- subject.after(interval_ms / 1000.0)
104
-
105
- expect(subject.wait_interval).to be_within(TIMER_QUANTUM).of(interval_ms / 1000.0)
106
- end
107
-
108
- describe "pause and continue timers" do
109
- before(:each) do
110
- @interval = TIMER_QUANTUM * 2
111
-
112
- @fired = false
113
- @timer = subject.after(@interval) { @fired = true }
114
- @fired2 = false
115
- @timer2 = subject.after(@interval) { @fired2 = true }
116
- end
117
-
118
- it "does not fire when paused" do
119
- @timer.pause
120
- subject.wait
121
- expect(@fired).to be false
122
- end
123
-
124
- it "fires when continued after pause" do
125
- @timer.pause
126
- subject.wait
127
- @timer.resume
128
-
129
- sleep @timer.interval
130
- subject.wait
131
-
132
- expect(@fired).to be true
133
- end
134
-
135
- it "can pause all timers at once" do
136
- subject.pause
137
- subject.wait
138
- expect(@fired).to be false
139
- expect(@fired2).to be false
140
- end
141
-
142
- it "can continue all timers at once" do
143
- subject.pause
144
- subject.wait
145
- subject.resume
146
-
147
- # We need to wait until we are sure both timers will fire, otherwise highly accurate clocks (e.g. JVM) may only fire the first timer, but not the second, because they are actually schedueled at different times.
148
- sleep TIMER_QUANTUM * 2
149
- subject.wait
150
-
151
- expect(@fired).to be true
152
- expect(@fired2).to be true
153
- end
154
-
155
- it "can fire the timer directly" do
156
- fired = false
157
- timer = subject.after( TIMER_QUANTUM * 1 ) { fired = true }
158
- timer.pause
159
- subject.wait
160
- expect(fired).not_to be true
161
- timer.resume
162
- expect(fired).not_to be true
163
- timer.fire
164
- expect(fired).to be true
165
- end
166
-
167
- end
168
-
169
- describe "delay timer" do
170
- it "adds appropriate amount of time to timer" do
171
- timer = subject.after(10)
172
- timer.delay(5)
173
- expect(timer.offset - subject.current_offset).to be_within(TIMER_QUANTUM).of(15)
174
- end
175
- end
176
-
177
- describe "delay timer collection" do
178
- it "delay on set adds appropriate amount of time to all timers" do
179
- timer = subject.after(10)
180
- timer2 = subject.after(20)
181
- subject.delay(5)
182
- expect(timer.offset - subject.current_offset).to be_within(TIMER_QUANTUM).of(15)
183
- expect(timer2.offset - subject.current_offset).to be_within(TIMER_QUANTUM).of(25)
184
- end
185
- end
186
-
187
- describe "on delaying a timer" do
188
- it "fires timers in the correct order" do
189
- result = []
190
-
191
- subject.after(TIMER_QUANTUM * 2) { result << :two }
192
- subject.after(TIMER_QUANTUM * 3) { result << :three }
193
- first = subject.after(TIMER_QUANTUM * 1) { result << :one }
194
- first.delay(TIMER_QUANTUM * 3)
195
-
196
- sleep TIMER_QUANTUM * 5
197
- subject.fire
198
-
199
- expect(result).to eq [:two, :three, :one]
200
- end
201
- end
202
-
203
- describe "Timer inspection" do
204
- it "before firing" do
205
- fired = false
206
- timer = subject.after(TIMER_QUANTUM * 5) { fired = true }
207
- timer.pause
208
- expect(fired).not_to be true
209
- expect(timer.inspect).to match(/\A#<Timers::Timer:[\da-f]+ fires in [-\.\de]+ seconds>\Z/)
210
- end
211
-
212
- it "after firing" do
213
- fired = false
214
- timer = subject.after(TIMER_QUANTUM) { fired = true }
215
-
216
- subject.wait
217
-
218
- expect(fired).to be true
219
- expect(timer.inspect).to match(/\A#<Timers::Timer:[\da-f]+ fired [-\.\de]+ seconds ago>\Z/)
220
- end
221
-
222
- it "recurring firing" do
223
- result = []
224
- timer = subject.every(TIMER_QUANTUM) { result << :foo }
225
-
226
- subject.wait
227
- expect(result).not_to be_empty
228
- expect(timer.inspect).to match(/\A#<Timers::Timer:[\da-f]+ fires in [-\.\de]+ seconds, recurs every #{sprintf("%0.2f", TIMER_QUANTUM)}>\Z/)
229
- end
230
- end
231
-
232
- describe "fires_in" do
233
- let(:interval) { TIMER_QUANTUM * 2 }
234
-
235
- it "calculates the interval until the next fire if it's recurring" do
236
- timer = subject.every(interval) { true }
237
- expect(timer.fires_in).to be_within(TIMER_QUANTUM).of(interval)
238
- end
239
-
240
- context "when timer is not recurring" do
241
- let!(:timer) { subject.after(interval) { true } }
242
-
243
- it "calculates the interval until the next fire if it hasn't already fired" do
244
- expect(timer.fires_in).to be_within(TIMER_QUANTUM).of(interval)
245
- end
246
-
247
- it "calculates the interval since last fire if already fired" do
248
- subject.wait
249
- sleep(interval)
250
- expect(timer.fires_in).to be_within(TIMER_QUANTUM).of(0 - interval)
251
- end
252
- end
253
- end
254
- end
@@ -1,100 +0,0 @@
1
- require 'spec_helper'
2
-
3
- # Event based timers:
4
-
5
- # Serviced 31812 events in 2.39075272 seconds, 13306.320832794887 e/s.
6
- # Thread ID: 7336700
7
- # Fiber ID: 30106340
8
- # Total: 2.384043
9
- # Sort by: self_time
10
-
11
- # %self total self wait child calls name
12
- # 13.48 0.510 0.321 0.000 0.189 369133 Timers::Events::Handle#<=>
13
- # 8.12 0.194 0.194 0.000 0.000 427278 Timers::Events::Handle#to_f
14
- # 4.55 0.109 0.109 0.000 0.000 427278 Float#<=>
15
- # 4.40 1.857 0.105 0.000 1.752 466376 *Timers::Events#bsearch
16
- # 4.30 0.103 0.103 0.000 0.000 402945 Float#to_f
17
- # 2.65 0.063 0.063 0.000 0.000 33812 Array#insert
18
- # 2.64 1.850 0.063 0.000 1.787 33812 Timers::Events#schedule
19
- # 2.40 1.930 0.057 0.000 1.873 33812 Timers::Timer#reset
20
- # 1.89 1.894 0.045 0.000 1.849 31812 Timers::Timer#fire
21
- # 1.69 1.966 0.040 0.000 1.926 31812 Timers::Events::Handle#fire
22
- # 1.35 0.040 0.032 0.000 0.008 33812 Timers::Events::Handle#initialize
23
- # 1.29 0.044 0.031 0.000 0.013 44451 Timers::Group#current_offset
24
-
25
- # SortedSet based timers:
26
-
27
- # Serviced 32516 events in 66.753277275 seconds, 487.1072288781219 e/s.
28
- # Thread ID: 15995640
29
- # Fiber ID: 38731780
30
- # Total: 66.716394
31
- # Sort by: self_time
32
-
33
- # %self total self wait child calls name
34
- # 54.73 49.718 36.513 0.000 13.205 57084873 Timers::Timer#<=>
35
- # 23.74 65.559 15.841 0.000 49.718 32534 Array#sort!
36
- # 19.79 13.205 13.205 0.000 0.000 57084873 Float#<=>
37
-
38
- # Max out events performance (on my computer):
39
- # Serviced 1142649 events in 11.194903921 seconds, 102068.70405115146 e/s.
40
-
41
- RSpec.describe Timers::Group do
42
-
43
- it "runs efficiently" do
44
- result = []
45
- range = (1..500)
46
- duration = 2.0
47
-
48
- total = 0
49
- range.each do |index|
50
- offset = index.to_f / range.max
51
- total += (duration / offset).floor
52
-
53
- subject.every(index.to_f / range.max, :strict) { result << index }
54
- end
55
-
56
- subject.wait while result.size < total
57
-
58
- rate = result.size.to_f / subject.current_offset
59
- puts "Serviced #{result.size} events in #{subject.current_offset} seconds, #{rate} e/s."
60
-
61
- expect(subject.current_offset).to be_within(TIMER_QUANTUM).of(duration)
62
- end
63
-
64
- =begin
65
- it "runs efficiently at high volume" do
66
- results = []
67
- range = (1..300)
68
- groups = (1..20)
69
- duration = 101
70
-
71
- timers = []
72
- @mutex = Mutex.new
73
- start = Time.now
74
- groups.each do |gi|
75
- timers << Thread.new {
76
- result = []
77
- timer = Timers::Group.new
78
- total = 0
79
- range.each do |ri|
80
- offset = ri.to_f / range.max
81
- total += (duration / offset).floor
82
- timer.every(ri.to_f / range.max, :strict) { result << ri }
83
- end
84
- timer.wait while result.size < total
85
- @mutex.synchronize { results += result }
86
-
87
- }
88
- end
89
- timers.each { |t| t.join }
90
- finish = Time.now
91
-
92
- rate = results.size.to_f / ( runtime = finish - start )
93
-
94
- puts "Serviced #{results.size} events in #{runtime} seconds, #{rate} e/s; across #{groups.max} timers."
95
-
96
- expect(runtime).to be_within(TIMER_QUANTUM).of(duration)
97
- end
98
- =end
99
-
100
- end
@@ -1,19 +0,0 @@
1
- require 'coveralls'
2
- Coveralls.wear!
3
-
4
- require 'bundler/setup'
5
- require 'timers'
6
-
7
- # Level of accuracy enforced by tests (50ms)
8
- TIMER_QUANTUM = 0.05
9
-
10
- RSpec.configure do |config|
11
- # Setting this config option `false` removes rspec-core's monkey patching of the
12
- # top level methods like `describe`, `shared_examples_for` and `shared_context`
13
- # on `main` and `Module`. The methods are always available through the `RSpec`
14
- # module like `RSpec.describe` regardless of this setting.
15
- # For backwards compatibility this defaults to `true`.
16
- #
17
- # https://relishapp.com/rspec/rspec-core/v/3-0/docs/configuration/global-namespace-dsl
18
- config.expose_dsl_globally = false
19
- end