polyphony 0.49.2 → 0.53.0
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/.github/workflows/test.yml +1 -1
- data/CHANGELOG.md +34 -0
- data/Gemfile.lock +7 -68
- data/TODO.md +37 -3
- data/examples/core/forking.rb +2 -2
- data/examples/core/nested.rb +21 -0
- data/examples/core/suspend.rb +13 -0
- data/examples/core/terminate_main_fiber.rb +12 -0
- data/examples/io/echo_server.rb +1 -0
- data/examples/io/tcp_proxy.rb +2 -2
- data/ext/polyphony/backend_common.h +58 -8
- data/ext/polyphony/backend_io_uring.c +223 -41
- data/ext/polyphony/backend_io_uring_context.c +1 -0
- data/ext/polyphony/backend_io_uring_context.h +1 -0
- data/ext/polyphony/backend_libev.c +322 -34
- data/ext/polyphony/event.c +1 -1
- data/ext/polyphony/extconf.rb +9 -2
- data/ext/polyphony/fiber.c +2 -1
- data/ext/polyphony/polyphony.c +102 -0
- data/ext/polyphony/polyphony.h +33 -2
- data/ext/polyphony/polyphony_ext.c +3 -0
- data/ext/polyphony/queue.c +1 -1
- data/ext/polyphony/runqueue.c +7 -1
- data/ext/polyphony/runqueue_ring_buffer.c +9 -0
- data/ext/polyphony/runqueue_ring_buffer.h +1 -0
- data/ext/polyphony/socket_extensions.c +33 -0
- data/ext/polyphony/thread.c +14 -0
- data/lib/polyphony/adapters/irb.rb +1 -1
- data/lib/polyphony/adapters/mysql2.rb +1 -1
- data/lib/polyphony/adapters/postgres.rb +5 -5
- data/lib/polyphony/adapters/process.rb +4 -4
- data/lib/polyphony/core/exceptions.rb +1 -0
- data/lib/polyphony/core/global_api.rb +6 -6
- data/lib/polyphony/core/sync.rb +1 -1
- data/lib/polyphony/core/throttler.rb +1 -1
- data/lib/polyphony/core/timer.rb +63 -20
- data/lib/polyphony/extensions/core.rb +5 -5
- data/lib/polyphony/extensions/fiber.rb +2 -0
- data/lib/polyphony/extensions/io.rb +21 -22
- data/lib/polyphony/extensions/openssl.rb +6 -6
- data/lib/polyphony/extensions/socket.rb +56 -47
- data/lib/polyphony/version.rb +1 -1
- data/polyphony.gemspec +6 -5
- data/test/helper.rb +1 -1
- data/test/stress.rb +2 -0
- data/test/test_backend.rb +69 -5
- data/test/test_fiber.rb +16 -0
- data/test/test_global_api.rb +2 -2
- data/test/test_io.rb +84 -1
- data/test/test_kernel.rb +1 -1
- data/test/test_signal.rb +1 -1
- data/test/test_socket.rb +61 -0
- data/test/test_timer.rb +41 -8
- metadata +22 -60
data/lib/polyphony/version.rb
CHANGED
data/polyphony.gemspec
CHANGED
|
@@ -22,12 +22,13 @@ Gem::Specification.new do |s|
|
|
|
22
22
|
s.required_ruby_version = '>= 2.6'
|
|
23
23
|
|
|
24
24
|
s.add_development_dependency 'rake-compiler', '1.1.1'
|
|
25
|
-
s.add_development_dependency 'minitest', '5.
|
|
25
|
+
s.add_development_dependency 'minitest', '5.14.4'
|
|
26
26
|
s.add_development_dependency 'minitest-reporters', '1.4.2'
|
|
27
27
|
s.add_development_dependency 'simplecov', '0.17.1'
|
|
28
28
|
s.add_development_dependency 'rubocop', '0.85.1'
|
|
29
29
|
s.add_development_dependency 'pry', '0.13.1'
|
|
30
30
|
|
|
31
|
+
s.add_development_dependency 'msgpack', '1.4.2'
|
|
31
32
|
s.add_development_dependency 'pg', '1.1.4'
|
|
32
33
|
s.add_development_dependency 'redis', '4.1.0'
|
|
33
34
|
s.add_development_dependency 'hiredis', '0.6.3'
|
|
@@ -37,8 +38,8 @@ Gem::Specification.new do |s|
|
|
|
37
38
|
s.add_development_dependency 'sequel', '5.34.0'
|
|
38
39
|
s.add_development_dependency 'httparty', '0.17.1'
|
|
39
40
|
|
|
40
|
-
s.add_development_dependency 'jekyll', '~>3.8.6'
|
|
41
|
-
s.add_development_dependency 'jekyll-remote-theme', '~>0.4.1'
|
|
42
|
-
s.add_development_dependency 'jekyll-seo-tag', '~>2.6.1'
|
|
43
|
-
s.add_development_dependency 'just-the-docs', '~>0.3.0'
|
|
41
|
+
# s.add_development_dependency 'jekyll', '~>3.8.6'
|
|
42
|
+
# s.add_development_dependency 'jekyll-remote-theme', '~>0.4.1'
|
|
43
|
+
# s.add_development_dependency 'jekyll-seo-tag', '~>2.6.1'
|
|
44
|
+
# s.add_development_dependency 'just-the-docs', '~>0.3.0'
|
|
44
45
|
end
|
data/test/helper.rb
CHANGED
data/test/stress.rb
CHANGED
data/test/test_backend.rb
CHANGED
|
@@ -125,12 +125,15 @@ class BackendTest < MiniTest::Test
|
|
|
125
125
|
assert_equal [:ready, 'foo', 'bar'], buf
|
|
126
126
|
end
|
|
127
127
|
|
|
128
|
-
|
|
129
|
-
|
|
128
|
+
Net = Polyphony::Net
|
|
129
|
+
|
|
130
|
+
def test_accept
|
|
131
|
+
server = Net.listening_socket_from_options('127.0.0.1', 1234, reuse_addr: true)
|
|
130
132
|
|
|
131
133
|
clients = []
|
|
132
|
-
server_fiber =
|
|
133
|
-
@backend.
|
|
134
|
+
server_fiber = spin_loop do
|
|
135
|
+
c = @backend.accept(server, TCPSocket)
|
|
136
|
+
clients << c
|
|
134
137
|
end
|
|
135
138
|
|
|
136
139
|
c1 = TCPSocket.new('127.0.0.1', 1234)
|
|
@@ -146,7 +149,32 @@ class BackendTest < MiniTest::Test
|
|
|
146
149
|
ensure
|
|
147
150
|
c1&.close
|
|
148
151
|
c2&.close
|
|
149
|
-
server_fiber
|
|
152
|
+
server_fiber&.stop
|
|
153
|
+
snooze
|
|
154
|
+
server&.close
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
def test_accept_loop
|
|
158
|
+
server = Net.listening_socket_from_options('127.0.0.1', 1235, reuse_addr: true)
|
|
159
|
+
|
|
160
|
+
clients = []
|
|
161
|
+
server_fiber = spin do
|
|
162
|
+
@backend.accept_loop(server, TCPSocket) { |c| clients << c }
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
c1 = TCPSocket.new('127.0.0.1', 1235)
|
|
166
|
+
sleep 0.01
|
|
167
|
+
|
|
168
|
+
assert_equal 1, clients.size
|
|
169
|
+
|
|
170
|
+
c2 = TCPSocket.new('127.0.0.1', 1235)
|
|
171
|
+
sleep 0.01
|
|
172
|
+
|
|
173
|
+
assert_equal 2, clients.size
|
|
174
|
+
ensure
|
|
175
|
+
c1&.close
|
|
176
|
+
c2&.close
|
|
177
|
+
server_fiber&.stop
|
|
150
178
|
snooze
|
|
151
179
|
server&.close
|
|
152
180
|
end
|
|
@@ -209,4 +237,40 @@ class BackendTest < MiniTest::Test
|
|
|
209
237
|
end
|
|
210
238
|
assert_equal [1], buffer
|
|
211
239
|
end
|
|
240
|
+
|
|
241
|
+
def test_splice
|
|
242
|
+
i1, o1 = IO.pipe
|
|
243
|
+
i2, o2 = IO.pipe
|
|
244
|
+
|
|
245
|
+
spin {
|
|
246
|
+
o2.splice(i1, 1000)
|
|
247
|
+
o2.close
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
o1.write('foobar')
|
|
251
|
+
result = i2.read
|
|
252
|
+
|
|
253
|
+
assert_equal 'foobar', result
|
|
254
|
+
end
|
|
255
|
+
|
|
256
|
+
def test_splice_to_eof
|
|
257
|
+
i1, o1 = IO.pipe
|
|
258
|
+
i2, o2 = IO.pipe
|
|
259
|
+
|
|
260
|
+
f = spin {
|
|
261
|
+
o2.splice_to_eof(i1, 1000)
|
|
262
|
+
o2.close
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
o1.write('foo')
|
|
266
|
+
result = i2.readpartial(1000)
|
|
267
|
+
assert_equal 'foo', result
|
|
268
|
+
|
|
269
|
+
o1.write('bar')
|
|
270
|
+
result = i2.readpartial(1000)
|
|
271
|
+
assert_equal 'bar', result
|
|
272
|
+
ensure
|
|
273
|
+
f.interrupt
|
|
274
|
+
f.await
|
|
275
|
+
end
|
|
212
276
|
end
|
data/test/test_fiber.rb
CHANGED
|
@@ -349,6 +349,22 @@ class FiberTest < MiniTest::Test
|
|
|
349
349
|
assert_equal [:foo, :terminate], buffer
|
|
350
350
|
end
|
|
351
351
|
|
|
352
|
+
CMD_TERMINATE_MAIN_FIBER = <<~BASH
|
|
353
|
+
ruby -rbundler/setup -rpolyphony -e"spin { sleep 0.1; Thread.current.main_fiber.terminate }; begin; sleep; rescue Polyphony::Terminate; STDOUT << 'terminated'; end" 2>&1
|
|
354
|
+
BASH
|
|
355
|
+
|
|
356
|
+
CMD_TERMINATE_CHILD_FIBER = <<~BASH
|
|
357
|
+
ruby -rbundler/setup -rpolyphony -e"f = spin { sleep }; spin { sleep 0.1; f.terminate }; f.await" 2>&1
|
|
358
|
+
BASH
|
|
359
|
+
|
|
360
|
+
def test_terminate_main_fiber
|
|
361
|
+
output = `#{CMD_TERMINATE_CHILD_FIBER}`
|
|
362
|
+
assert_equal '', output
|
|
363
|
+
|
|
364
|
+
output = `#{CMD_TERMINATE_MAIN_FIBER}`
|
|
365
|
+
assert_equal 'terminated', output
|
|
366
|
+
end
|
|
367
|
+
|
|
352
368
|
def test_interrupt_timer
|
|
353
369
|
result = []
|
|
354
370
|
f = Fiber.current.spin do
|
data/test/test_global_api.rb
CHANGED
|
@@ -160,10 +160,10 @@ class MoveOnAfterTest < MiniTest::Test
|
|
|
160
160
|
end
|
|
161
161
|
t1 = Time.now
|
|
162
162
|
assert_equal 1, o
|
|
163
|
-
assert_in_range 0.008..0.
|
|
163
|
+
assert_in_range 0.008..0.015, t1 - t0
|
|
164
164
|
|
|
165
165
|
t0 = Time.now
|
|
166
|
-
o = move_on_after(0.
|
|
166
|
+
o = move_on_after(0.05, with_value: 1) do
|
|
167
167
|
move_on_after(0.01, with_value: 2) do
|
|
168
168
|
sleep 1
|
|
169
169
|
end
|
data/test/test_io.rb
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require_relative 'helper'
|
|
4
|
+
require 'msgpack'
|
|
4
5
|
|
|
5
6
|
class IOTest < MiniTest::Test
|
|
6
7
|
def setup
|
|
@@ -110,7 +111,7 @@ class IOTest < MiniTest::Test
|
|
|
110
111
|
assert_equal [], buf
|
|
111
112
|
|
|
112
113
|
o << "ulous\n"
|
|
113
|
-
|
|
114
|
+
sleep 0.01
|
|
114
115
|
assert_equal ["fabulous\n"], buf
|
|
115
116
|
|
|
116
117
|
o.close
|
|
@@ -173,6 +174,88 @@ class IOTest < MiniTest::Test
|
|
|
173
174
|
|
|
174
175
|
assert_equal 'hello: world', buf
|
|
175
176
|
end
|
|
177
|
+
|
|
178
|
+
def test_feed_loop_with_block
|
|
179
|
+
i, o = IO.pipe
|
|
180
|
+
unpacker = MessagePack::Unpacker.new
|
|
181
|
+
buffer = []
|
|
182
|
+
reader = spin do
|
|
183
|
+
i.feed_loop(unpacker, :feed_each) { |msg| buffer << msg }
|
|
184
|
+
end
|
|
185
|
+
o << 'foo'.to_msgpack
|
|
186
|
+
sleep 0.01
|
|
187
|
+
assert_equal ['foo'], buffer
|
|
188
|
+
|
|
189
|
+
o << 'bar'.to_msgpack
|
|
190
|
+
sleep 0.01
|
|
191
|
+
assert_equal ['foo', 'bar'], buffer
|
|
192
|
+
|
|
193
|
+
o << 'baz'.to_msgpack
|
|
194
|
+
sleep 0.01
|
|
195
|
+
assert_equal ['foo', 'bar', 'baz'], buffer
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
class Receiver1
|
|
199
|
+
attr_reader :buffer
|
|
200
|
+
|
|
201
|
+
def initialize
|
|
202
|
+
@buffer = []
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
def recv(obj)
|
|
206
|
+
@buffer << obj
|
|
207
|
+
end
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
def test_feed_loop_without_block
|
|
211
|
+
i, o = IO.pipe
|
|
212
|
+
receiver = Receiver1.new
|
|
213
|
+
reader = spin do
|
|
214
|
+
i.feed_loop(receiver, :recv)
|
|
215
|
+
end
|
|
216
|
+
o << 'foo'
|
|
217
|
+
sleep 0.01
|
|
218
|
+
assert_equal ['foo'], receiver.buffer
|
|
219
|
+
|
|
220
|
+
o << 'bar'
|
|
221
|
+
sleep 0.01
|
|
222
|
+
assert_equal ['foo', 'bar'], receiver.buffer
|
|
223
|
+
|
|
224
|
+
o << 'baz'
|
|
225
|
+
sleep 0.01
|
|
226
|
+
assert_equal ['foo', 'bar', 'baz'], receiver.buffer
|
|
227
|
+
end
|
|
228
|
+
|
|
229
|
+
class Receiver2
|
|
230
|
+
attr_reader :buffer
|
|
231
|
+
|
|
232
|
+
def initialize
|
|
233
|
+
@buffer = []
|
|
234
|
+
end
|
|
235
|
+
|
|
236
|
+
def call(obj)
|
|
237
|
+
@buffer << obj
|
|
238
|
+
end
|
|
239
|
+
end
|
|
240
|
+
|
|
241
|
+
def test_feed_loop_without_method
|
|
242
|
+
i, o = IO.pipe
|
|
243
|
+
receiver = Receiver2.new
|
|
244
|
+
reader = spin do
|
|
245
|
+
i.feed_loop(receiver)
|
|
246
|
+
end
|
|
247
|
+
o << 'foo'
|
|
248
|
+
sleep 0.01
|
|
249
|
+
assert_equal ['foo'], receiver.buffer
|
|
250
|
+
|
|
251
|
+
o << 'bar'
|
|
252
|
+
sleep 0.01
|
|
253
|
+
assert_equal ['foo', 'bar'], receiver.buffer
|
|
254
|
+
|
|
255
|
+
o << 'baz'
|
|
256
|
+
sleep 0.01
|
|
257
|
+
assert_equal ['foo', 'bar', 'baz'], receiver.buffer
|
|
258
|
+
end
|
|
176
259
|
end
|
|
177
260
|
|
|
178
261
|
class IOClassMethodsTest < MiniTest::Test
|
data/test/test_kernel.rb
CHANGED
|
@@ -21,7 +21,7 @@ class KernelTest < MiniTest::Test
|
|
|
21
21
|
|
|
22
22
|
def test_Kernel_system_singleton_method
|
|
23
23
|
assert_equal true, Kernel.system("which ruby > /dev/null 2>&1")
|
|
24
|
-
assert_equal false, Kernel.system("
|
|
24
|
+
assert_equal false, Kernel.system("azertyuiop > /dev/null 2>&1")
|
|
25
25
|
end
|
|
26
26
|
|
|
27
27
|
def patch_open3
|
data/test/test_signal.rb
CHANGED
data/test/test_socket.rb
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
require_relative 'helper'
|
|
4
4
|
require 'fileutils'
|
|
5
|
+
require 'msgpack'
|
|
5
6
|
|
|
6
7
|
class SocketTest < MiniTest::Test
|
|
7
8
|
def setup
|
|
@@ -33,6 +34,66 @@ class SocketTest < MiniTest::Test
|
|
|
33
34
|
server&.close
|
|
34
35
|
end
|
|
35
36
|
|
|
37
|
+
# sending multiple strings at once
|
|
38
|
+
def test_sendv
|
|
39
|
+
port = rand(1234..5678)
|
|
40
|
+
server = TCPServer.new('127.0.0.1', port)
|
|
41
|
+
|
|
42
|
+
server_fiber = spin do
|
|
43
|
+
while (socket = server.accept)
|
|
44
|
+
spin do
|
|
45
|
+
while (data = socket.gets(8192))
|
|
46
|
+
socket.write("you said ", data)
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
snooze
|
|
53
|
+
client = TCPSocket.new('127.0.0.1', port)
|
|
54
|
+
client.write("1234\n")
|
|
55
|
+
assert_equal "you said 1234\n", client.recv(8192)
|
|
56
|
+
client.close
|
|
57
|
+
ensure
|
|
58
|
+
server_fiber&.stop
|
|
59
|
+
server_fiber&.await
|
|
60
|
+
server&.close
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def test_feed_loop
|
|
65
|
+
port = rand(1234..5678)
|
|
66
|
+
server = TCPServer.new('127.0.0.1', port)
|
|
67
|
+
|
|
68
|
+
server_fiber = spin do
|
|
69
|
+
reader = MessagePack::Unpacker.new
|
|
70
|
+
while (socket = server.accept)
|
|
71
|
+
spin do
|
|
72
|
+
socket.feed_loop(reader, :feed_each) do |msg|
|
|
73
|
+
msg = { 'result' => msg['x'] + msg['y'] }
|
|
74
|
+
socket << msg.to_msgpack
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
snooze
|
|
81
|
+
client = TCPSocket.new('127.0.0.1', port)
|
|
82
|
+
reader = MessagePack::Unpacker.new
|
|
83
|
+
client << { 'x' => 13, 'y' => 14 }.to_msgpack
|
|
84
|
+
result = nil
|
|
85
|
+
client.feed_loop(reader, :feed_each) do |msg|
|
|
86
|
+
result = msg
|
|
87
|
+
break
|
|
88
|
+
end
|
|
89
|
+
assert_equal({ 'result' => 27}, result)
|
|
90
|
+
client.close
|
|
91
|
+
ensure
|
|
92
|
+
server_fiber&.stop
|
|
93
|
+
server_fiber&.await
|
|
94
|
+
server&.close
|
|
95
|
+
end
|
|
96
|
+
|
|
36
97
|
def test_unix_socket
|
|
37
98
|
path = '/tmp/test_unix_socket'
|
|
38
99
|
FileUtils.rm(path) rescue nil
|
data/test/test_timer.rb
CHANGED
|
@@ -11,7 +11,7 @@ class TimerMoveOnAfterTest < MiniTest::Test
|
|
|
11
11
|
@timer.stop
|
|
12
12
|
end
|
|
13
13
|
|
|
14
|
-
def
|
|
14
|
+
def test_timer_move_on_after
|
|
15
15
|
t0 = Time.now
|
|
16
16
|
v = @timer.move_on_after(0.1) do
|
|
17
17
|
sleep 1
|
|
@@ -23,7 +23,7 @@ class TimerMoveOnAfterTest < MiniTest::Test
|
|
|
23
23
|
assert_nil v
|
|
24
24
|
end
|
|
25
25
|
|
|
26
|
-
def
|
|
26
|
+
def test_timer_move_on_after_with_value
|
|
27
27
|
t0 = Time.now
|
|
28
28
|
v = @timer.move_on_after(0.01, with_value: :bar) do
|
|
29
29
|
sleep 1
|
|
@@ -35,7 +35,7 @@ class TimerMoveOnAfterTest < MiniTest::Test
|
|
|
35
35
|
assert_equal :bar, v
|
|
36
36
|
end
|
|
37
37
|
|
|
38
|
-
def
|
|
38
|
+
def test_timer_move_on_after_with_reset
|
|
39
39
|
t0 = Time.now
|
|
40
40
|
v = @timer.move_on_after(0.01, with_value: :moved_on) do
|
|
41
41
|
sleep 0.007
|
|
@@ -48,7 +48,7 @@ class TimerMoveOnAfterTest < MiniTest::Test
|
|
|
48
48
|
t1 = Time.now
|
|
49
49
|
|
|
50
50
|
assert_nil v
|
|
51
|
-
assert_in_range 0.
|
|
51
|
+
assert_in_range 0.015..0.03, t1 - t0
|
|
52
52
|
end
|
|
53
53
|
end
|
|
54
54
|
|
|
@@ -61,7 +61,7 @@ class TimerCancelAfterTest < MiniTest::Test
|
|
|
61
61
|
@timer.stop
|
|
62
62
|
end
|
|
63
63
|
|
|
64
|
-
def
|
|
64
|
+
def test_timer_cancel_after
|
|
65
65
|
t0 = Time.now
|
|
66
66
|
|
|
67
67
|
assert_raises Polyphony::Cancel do
|
|
@@ -74,7 +74,7 @@ class TimerCancelAfterTest < MiniTest::Test
|
|
|
74
74
|
assert_in_range 0.01..0.03, t1 - t0
|
|
75
75
|
end
|
|
76
76
|
|
|
77
|
-
def
|
|
77
|
+
def test_timer_cancel_after_with_reset
|
|
78
78
|
t0 = Time.now
|
|
79
79
|
@timer.cancel_after(0.01) do
|
|
80
80
|
sleep 0.007
|
|
@@ -82,13 +82,13 @@ class TimerCancelAfterTest < MiniTest::Test
|
|
|
82
82
|
sleep 0.007
|
|
83
83
|
end
|
|
84
84
|
t1 = Time.now
|
|
85
|
-
assert_in_range 0.
|
|
85
|
+
assert_in_range 0.012..0.024, t1 - t0
|
|
86
86
|
end
|
|
87
87
|
|
|
88
88
|
class CustomException < Exception
|
|
89
89
|
end
|
|
90
90
|
|
|
91
|
-
def
|
|
91
|
+
def test_timer_cancel_after_with_custom_exception
|
|
92
92
|
assert_raises CustomException do
|
|
93
93
|
@timer.cancel_after(0.01, with_exception: CustomException) do
|
|
94
94
|
sleep 1
|
|
@@ -122,3 +122,36 @@ class TimerCancelAfterTest < MiniTest::Test
|
|
|
122
122
|
end
|
|
123
123
|
end
|
|
124
124
|
end
|
|
125
|
+
|
|
126
|
+
class TimerMiscTest < MiniTest::Test
|
|
127
|
+
def setup
|
|
128
|
+
@timer = Polyphony::Timer.new(resolution: 0.001)
|
|
129
|
+
sleep 0
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
def teardown
|
|
133
|
+
@timer.stop
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
def test_timer_after
|
|
137
|
+
buffer = []
|
|
138
|
+
f = @timer.after(0.01) { buffer << 2 }
|
|
139
|
+
assert_kind_of Fiber, f
|
|
140
|
+
snooze
|
|
141
|
+
assert_equal [], buffer
|
|
142
|
+
sleep 0.1
|
|
143
|
+
p :post_sleep
|
|
144
|
+
assert_equal [2], buffer
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
def test_timer_every
|
|
148
|
+
buffer = []
|
|
149
|
+
t0 = Time.now
|
|
150
|
+
f = spin do
|
|
151
|
+
@timer.every(0.01) { buffer << 1 }
|
|
152
|
+
end
|
|
153
|
+
sleep 0.05
|
|
154
|
+
f.stop
|
|
155
|
+
assert_in_range 4..6, buffer.size
|
|
156
|
+
end
|
|
157
|
+
end
|