polyphony 0.70 → 0.73.1
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/FUNDING.yml +1 -0
- data/.github/workflows/test.yml +3 -2
- data/.gitignore +3 -1
- data/CHANGELOG.md +32 -4
- data/Gemfile.lock +11 -11
- data/TODO.md +1 -1
- data/bin/pdbg +1 -1
- data/bin/polyphony-debug +0 -0
- data/bin/stress.rb +0 -0
- data/bin/test +0 -0
- data/docs/_user-guide/all-about-timers.md +1 -1
- data/docs/api-reference/exception.md +5 -1
- data/docs/api-reference/fiber.md +2 -2
- data/docs/faq.md +1 -1
- data/docs/getting-started/overview.md +8 -8
- data/docs/getting-started/tutorial.md +3 -3
- data/docs/main-concepts/concurrency.md +1 -1
- data/docs/main-concepts/extending.md +3 -3
- data/docs/main-concepts/fiber-scheduling.md +1 -1
- data/examples/core/calc.rb +37 -0
- data/examples/core/calc_with_restart.rb +40 -0
- data/examples/core/calc_with_supervise.rb +37 -0
- data/examples/core/message_based_supervision.rb +1 -1
- data/examples/core/ring.rb +29 -0
- data/examples/io/rack_server.rb +1 -1
- data/examples/io/tunnel.rb +1 -1
- data/examples/performance/fiber_transfer.rb +1 -1
- data/examples/performance/line_splitting.rb +1 -1
- data/examples/performance/thread-vs-fiber/compare.rb +1 -1
- data/ext/polyphony/backend_common.c +15 -9
- data/ext/polyphony/backend_common.h +1 -1
- data/ext/polyphony/backend_io_uring.c +56 -64
- data/ext/polyphony/backend_io_uring_context.c +1 -1
- data/ext/polyphony/backend_io_uring_context.h +1 -1
- data/ext/polyphony/backend_libev.c +36 -30
- data/ext/polyphony/extconf.rb +25 -13
- data/ext/polyphony/polyphony.h +5 -1
- data/ext/polyphony/queue.c +2 -2
- data/ext/polyphony/runqueue_ring_buffer.c +3 -2
- data/ext/polyphony/thread.c +1 -1
- data/lib/polyphony/adapters/irb.rb +11 -1
- data/lib/polyphony/{extensions → core}/debug.rb +0 -0
- data/lib/polyphony/core/global_api.rb +3 -6
- data/lib/polyphony/core/timer.rb +2 -2
- data/lib/polyphony/debugger.rb +3 -3
- data/lib/polyphony/extensions/exception.rb +45 -0
- data/lib/polyphony/extensions/fiber.rb +27 -9
- data/lib/polyphony/extensions/io.rb +2 -2
- data/lib/polyphony/extensions/{core.rb → kernel.rb} +0 -73
- data/lib/polyphony/extensions/openssl.rb +20 -5
- data/lib/polyphony/extensions/process.rb +19 -0
- data/lib/polyphony/extensions/socket.rb +3 -4
- data/lib/polyphony/extensions/timeout.rb +10 -0
- data/lib/polyphony/extensions.rb +9 -0
- data/lib/polyphony/version.rb +1 -1
- data/lib/polyphony.rb +2 -5
- data/polyphony.gemspec +1 -1
- data/test/coverage.rb +2 -2
- data/test/stress.rb +1 -1
- data/test/test_backend.rb +12 -12
- data/test/test_event.rb +1 -1
- data/test/test_ext.rb +1 -1
- data/test/test_fiber.rb +52 -7
- data/test/test_global_api.rb +16 -3
- data/test/test_io.rb +3 -3
- data/test/test_process_supervision.rb +1 -1
- data/test/test_queue.rb +6 -6
- data/test/test_signal.rb +20 -1
- data/test/test_socket.rb +12 -10
- data/test/test_supervise.rb +85 -0
- data/test/test_sync.rb +2 -2
- data/test/test_thread.rb +22 -2
- data/test/test_thread_pool.rb +1 -1
- data/test/test_throttler.rb +1 -1
- data/test/test_timer.rb +2 -2
- data/test/test_trace.rb +1 -1
- metadata +13 -4
data/test/stress.rb
CHANGED
data/test/test_backend.rb
CHANGED
@@ -36,7 +36,7 @@ class BackendTest < MiniTest::Test
|
|
36
36
|
f = spin { @backend.read(i, buf, 5, false, 0) }
|
37
37
|
@backend.write(o, 'Hello world')
|
38
38
|
return_value = f.await
|
39
|
-
|
39
|
+
|
40
40
|
assert_equal 'Hello', buf
|
41
41
|
assert_equal return_value, buf
|
42
42
|
end
|
@@ -51,7 +51,7 @@ class BackendTest < MiniTest::Test
|
|
51
51
|
snooze
|
52
52
|
o.close
|
53
53
|
return_value = f.await
|
54
|
-
|
54
|
+
|
55
55
|
assert_equal 'Hello', buf
|
56
56
|
assert_equal return_value, buf
|
57
57
|
end
|
@@ -66,7 +66,7 @@ class BackendTest < MiniTest::Test
|
|
66
66
|
snooze
|
67
67
|
o.close
|
68
68
|
return_value = f.await
|
69
|
-
|
69
|
+
|
70
70
|
assert_equal 'Hello world', buf
|
71
71
|
assert_equal return_value, buf
|
72
72
|
end
|
@@ -77,7 +77,7 @@ class BackendTest < MiniTest::Test
|
|
77
77
|
f = spin { @backend.read(i, buf, 20, false, 0) }
|
78
78
|
@backend.write(o, 'blah')
|
79
79
|
return_value = f.await
|
80
|
-
|
80
|
+
|
81
81
|
assert_equal 'blah', buf
|
82
82
|
assert_equal return_value, buf
|
83
83
|
|
@@ -85,7 +85,7 @@ class BackendTest < MiniTest::Test
|
|
85
85
|
f = spin { @backend.read(i, buf, 20, false, -1) }
|
86
86
|
@backend.write(o, 'klmn')
|
87
87
|
return_value = f.await
|
88
|
-
|
88
|
+
|
89
89
|
assert_equal 'abcdefghijklmn', buf
|
90
90
|
assert_equal return_value, buf
|
91
91
|
|
@@ -93,7 +93,7 @@ class BackendTest < MiniTest::Test
|
|
93
93
|
f = spin { @backend.read(i, buf, 20, false, 3) }
|
94
94
|
@backend.write(o, 'DEF')
|
95
95
|
return_value = f.await
|
96
|
-
|
96
|
+
|
97
97
|
assert_equal 'abcDEF', buf
|
98
98
|
assert_equal return_value, buf
|
99
99
|
end
|
@@ -109,12 +109,12 @@ class BackendTest < MiniTest::Test
|
|
109
109
|
|
110
110
|
o << data
|
111
111
|
o.close
|
112
|
-
|
112
|
+
|
113
113
|
buf = +''
|
114
114
|
|
115
115
|
@backend.read(i, buf, 4096, false, -1)
|
116
116
|
assert_equal 4096, buf.bytesize
|
117
|
-
|
117
|
+
|
118
118
|
@backend.read(i, buf, 1, false, -1)
|
119
119
|
assert_equal 4097, buf.bytesize
|
120
120
|
|
@@ -129,7 +129,7 @@ class BackendTest < MiniTest::Test
|
|
129
129
|
@backend.post_fork
|
130
130
|
exit(42)
|
131
131
|
end
|
132
|
-
|
132
|
+
|
133
133
|
result = @backend.waitpid(pid)
|
134
134
|
assert_equal [pid, 42], result
|
135
135
|
end
|
@@ -427,7 +427,7 @@ class BackendTest < MiniTest::Test
|
|
427
427
|
counter = 0
|
428
428
|
|
429
429
|
@backend.idle_proc = proc { counter += 1 }
|
430
|
-
|
430
|
+
|
431
431
|
3.times { snooze }
|
432
432
|
assert_equal 0, counter
|
433
433
|
|
@@ -488,7 +488,7 @@ class BackendChainTest < MiniTest::Test
|
|
488
488
|
|
489
489
|
snooze
|
490
490
|
client = TCPSocket.new('127.0.0.1', port)
|
491
|
-
|
491
|
+
|
492
492
|
result = Thread.backend.chain(
|
493
493
|
[:send, client, 'hello', 0],
|
494
494
|
[:send, client, " world\n", 0]
|
@@ -512,7 +512,7 @@ class BackendChainTest < MiniTest::Test
|
|
512
512
|
while true
|
513
513
|
len = o.splice(from, 8192)
|
514
514
|
break if len == 0
|
515
|
-
|
515
|
+
|
516
516
|
backend.chain(
|
517
517
|
[:write, to, chunk_header(len)],
|
518
518
|
[:splice, i, to, len]
|
data/test/test_event.rb
CHANGED
data/test/test_ext.rb
CHANGED
data/test/test_fiber.rb
CHANGED
@@ -47,7 +47,7 @@ class FiberTest < MiniTest::Test
|
|
47
47
|
f1 = spin { :foo }
|
48
48
|
f2 = spin { :bar }
|
49
49
|
4.times { snooze }
|
50
|
-
|
50
|
+
|
51
51
|
assert_equal [:foo, :bar], Fiber.await(f1, f2)
|
52
52
|
end
|
53
53
|
|
@@ -739,7 +739,7 @@ class FiberTest < MiniTest::Test
|
|
739
739
|
def test_setup_raw
|
740
740
|
buffer = []
|
741
741
|
f = Fiber.new { buffer << receive }
|
742
|
-
|
742
|
+
|
743
743
|
assert_nil f.thread
|
744
744
|
snooze
|
745
745
|
f.setup_raw
|
@@ -771,10 +771,11 @@ class FiberTest < MiniTest::Test
|
|
771
771
|
|
772
772
|
snooze
|
773
773
|
assert_equal parent, child.parent
|
774
|
-
child.detach
|
774
|
+
result = child.detach
|
775
|
+
assert_equal result, child
|
775
776
|
assert_equal Fiber.current, child.parent
|
776
777
|
parent.await
|
777
|
-
|
778
|
+
|
778
779
|
child << :bye
|
779
780
|
child.await
|
780
781
|
|
@@ -807,7 +808,7 @@ class FiberTest < MiniTest::Test
|
|
807
808
|
child.attach_to(new_parent)
|
808
809
|
assert_equal new_parent, child.parent
|
809
810
|
parent.await
|
810
|
-
|
811
|
+
|
811
812
|
child << :bye
|
812
813
|
new_parent << :bye_new_parent
|
813
814
|
snooze
|
@@ -820,6 +821,29 @@ class FiberTest < MiniTest::Test
|
|
820
821
|
:bye_new_parent
|
821
822
|
], buf
|
822
823
|
end
|
824
|
+
|
825
|
+
def test_attach_all_children_to
|
826
|
+
children = []
|
827
|
+
f1 = spin do
|
828
|
+
3.times {
|
829
|
+
children << spin { receive }
|
830
|
+
}
|
831
|
+
Fiber.current.parent << :ok
|
832
|
+
receive
|
833
|
+
end
|
834
|
+
|
835
|
+
result = receive
|
836
|
+
assert_equal :ok, result
|
837
|
+
assert_equal 3, children.size
|
838
|
+
|
839
|
+
f2 = spin { supervise }
|
840
|
+
f1.attach_all_children_to(f2)
|
841
|
+
|
842
|
+
snooze
|
843
|
+
|
844
|
+
assert_equal [], f1.children
|
845
|
+
assert_equal children, f2.children
|
846
|
+
end
|
823
847
|
end
|
824
848
|
|
825
849
|
class MailboxTest < MiniTest::Test
|
@@ -949,6 +973,27 @@ class MailboxTest < MiniTest::Test
|
|
949
973
|
assert_equal ['foo'] * 100, messages
|
950
974
|
end
|
951
975
|
|
976
|
+
def test_receive_exception
|
977
|
+
e = RuntimeError.new 'foo'
|
978
|
+
spin { Fiber.current.parent << e }
|
979
|
+
r = receive
|
980
|
+
assert_equal e, r
|
981
|
+
|
982
|
+
spin { Fiber.current.parent.schedule e }
|
983
|
+
assert_raises(RuntimeError) { receive }
|
984
|
+
end
|
985
|
+
|
986
|
+
def test_receive_cross_thread_exception
|
987
|
+
e = RuntimeError.new 'foo'
|
988
|
+
f = Fiber.current
|
989
|
+
Thread.new { f << e }
|
990
|
+
r = receive
|
991
|
+
assert_equal e, r
|
992
|
+
|
993
|
+
Thread.new { f.schedule e }
|
994
|
+
assert_raises(RuntimeError) { receive }
|
995
|
+
end
|
996
|
+
|
952
997
|
def test_receive_all_pending
|
953
998
|
assert_equal [], receive_all_pending
|
954
999
|
|
@@ -1105,7 +1150,7 @@ class RestartTest < MiniTest::Test
|
|
1105
1150
|
assert_equal [1], buffer
|
1106
1151
|
snooze
|
1107
1152
|
assert_equal [1, 1], buffer
|
1108
|
-
|
1153
|
+
|
1109
1154
|
f << 'foo'
|
1110
1155
|
sleep 0.1
|
1111
1156
|
assert_equal [1, 1, 2], buffer
|
@@ -1231,7 +1276,7 @@ class DebugTest < MiniTest::Test
|
|
1231
1276
|
assert_equal true, f.__parked__?
|
1232
1277
|
10.times { snooze }
|
1233
1278
|
assert_equal [], buf
|
1234
|
-
|
1279
|
+
|
1235
1280
|
f.__unpark__
|
1236
1281
|
assert_nil f.__parked__?
|
1237
1282
|
10.times { snooze }
|
data/test/test_global_api.rb
CHANGED
@@ -280,7 +280,7 @@ class SpinLoopTest < MiniTest::Test
|
|
280
280
|
def test_spin_loop_location
|
281
281
|
location = /^#{__FILE__}:#{__LINE__ + 1}/
|
282
282
|
f = spin_loop { snooze }
|
283
|
-
|
283
|
+
|
284
284
|
assert_match location, f.location
|
285
285
|
end
|
286
286
|
|
@@ -402,7 +402,7 @@ class ThrottledLoopTest < MiniTest::Test
|
|
402
402
|
f.await
|
403
403
|
t1 = Time.now
|
404
404
|
assert_in_range 0.075..0.15, t1 - t0 if IS_LINUX
|
405
|
-
assert_equal [1, 2, 3, 4, 5], buffer
|
405
|
+
assert_equal [1, 2, 3, 4, 5], buffer
|
406
406
|
end
|
407
407
|
end
|
408
408
|
|
@@ -412,7 +412,7 @@ class GlobalAPIEtcTest < MiniTest::Test
|
|
412
412
|
f = after(0.001) { buffer << 2 }
|
413
413
|
snooze
|
414
414
|
assert_equal [], buffer
|
415
|
-
sleep 0.
|
415
|
+
sleep 0.0015
|
416
416
|
assert_equal [2], buffer
|
417
417
|
end
|
418
418
|
|
@@ -429,6 +429,19 @@ class GlobalAPIEtcTest < MiniTest::Test
|
|
429
429
|
assert_in_range 4..6, buffer.size
|
430
430
|
end
|
431
431
|
|
432
|
+
def test_every_with_slow_op
|
433
|
+
skip unless IS_LINUX
|
434
|
+
|
435
|
+
buffer = []
|
436
|
+
t0 = Time.now
|
437
|
+
f = spin do
|
438
|
+
every(0.01) { sleep 0.05; buffer << 1 }
|
439
|
+
end
|
440
|
+
sleep 0.15
|
441
|
+
f.stop
|
442
|
+
assert_in_range 2..3, buffer.size
|
443
|
+
end
|
444
|
+
|
432
445
|
def test_sleep
|
433
446
|
t0 = Time.now
|
434
447
|
sleep 0.1
|
data/test/test_io.rb
CHANGED
@@ -107,10 +107,10 @@ class IOTest < MiniTest::Test
|
|
107
107
|
sleep 0.01
|
108
108
|
o << 'hi'
|
109
109
|
}
|
110
|
-
assert_equal 'hi', i.readpartial(2)
|
110
|
+
assert_equal 'hi', i.readpartial(2)
|
111
111
|
o.close
|
112
112
|
|
113
|
-
assert_raises(EOFError) { i.readpartial(1) }
|
113
|
+
assert_raises(EOFError) { i.readpartial(1) }
|
114
114
|
end
|
115
115
|
|
116
116
|
def test_gets
|
@@ -132,7 +132,7 @@ class IOTest < MiniTest::Test
|
|
132
132
|
f << Fiber.current
|
133
133
|
sleep 0.05
|
134
134
|
assert_equal [], buf
|
135
|
-
|
135
|
+
|
136
136
|
o << "ulous\n"
|
137
137
|
receive
|
138
138
|
assert_equal ["fabulous\n"], buf
|
data/test/test_queue.rb
CHANGED
@@ -70,7 +70,7 @@ class QueueTest < MiniTest::Test
|
|
70
70
|
|
71
71
|
def test_empty?
|
72
72
|
assert @queue.empty?
|
73
|
-
|
73
|
+
|
74
74
|
@queue << :foo
|
75
75
|
assert !@queue.empty?
|
76
76
|
|
@@ -82,7 +82,7 @@ class QueueTest < MiniTest::Test
|
|
82
82
|
f1 = spin { @queue.shift }
|
83
83
|
f2 = spin { @queue.shift }
|
84
84
|
f3 = spin { @queue.shift }
|
85
|
-
|
85
|
+
|
86
86
|
# let fibers run
|
87
87
|
snooze
|
88
88
|
|
@@ -99,7 +99,7 @@ class QueueTest < MiniTest::Test
|
|
99
99
|
|
100
100
|
def test_fiber_removal_from_queue_simple
|
101
101
|
f1 = spin { @queue.shift }
|
102
|
-
|
102
|
+
|
103
103
|
# let fibers run
|
104
104
|
snooze
|
105
105
|
|
@@ -114,11 +114,11 @@ class QueueTest < MiniTest::Test
|
|
114
114
|
assert_equal 0, @queue.size
|
115
115
|
|
116
116
|
@queue.push 1
|
117
|
-
|
117
|
+
|
118
118
|
assert_equal 1, @queue.size
|
119
119
|
|
120
120
|
@queue.push 2
|
121
|
-
|
121
|
+
|
122
122
|
assert_equal 2, @queue.size
|
123
123
|
|
124
124
|
@queue.shift
|
@@ -231,7 +231,7 @@ class CappedQueueTest < MiniTest::Test
|
|
231
231
|
i = 0
|
232
232
|
spin_loop do
|
233
233
|
i += 1
|
234
|
-
snooze
|
234
|
+
snooze
|
235
235
|
end
|
236
236
|
|
237
237
|
5.times { snooze }
|
data/test/test_signal.rb
CHANGED
@@ -93,4 +93,23 @@ class SignalTrapTest < Minitest::Test
|
|
93
93
|
buffer = i.read
|
94
94
|
assert_equal "INT\n", buffer
|
95
95
|
end
|
96
|
-
|
96
|
+
|
97
|
+
def test_busy_signal_handling
|
98
|
+
i, o = IO.pipe
|
99
|
+
pid = Polyphony.fork do
|
100
|
+
main = Fiber.current
|
101
|
+
trap('INT') { o.puts 'INT'; o.close; main.stop }
|
102
|
+
i.close
|
103
|
+
f1 = spin_loop { snooze }
|
104
|
+
f2 = spin_loop { snooze }
|
105
|
+
f1.await
|
106
|
+
end
|
107
|
+
|
108
|
+
o.close
|
109
|
+
sleep 0.1
|
110
|
+
Process.kill('INT', pid)
|
111
|
+
Thread.current.backend.waitpid(pid)
|
112
|
+
buffer = i.read
|
113
|
+
assert_equal "INT\n", buffer
|
114
|
+
end
|
115
|
+
end
|
data/test/test_socket.rb
CHANGED
@@ -9,9 +9,16 @@ class SocketTest < MiniTest::Test
|
|
9
9
|
super
|
10
10
|
end
|
11
11
|
|
12
|
-
def
|
13
|
-
port = rand(
|
12
|
+
def start_tcp_server_on_random_port
|
13
|
+
port = rand(1100..60000)
|
14
14
|
server = TCPServer.new('127.0.0.1', port)
|
15
|
+
[port, server]
|
16
|
+
rescue Errno::EADDRINUSE
|
17
|
+
retry
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_tcp
|
21
|
+
port, server = start_tcp_server_on_random_port
|
15
22
|
server_fiber = spin do
|
16
23
|
while (socket = server.accept)
|
17
24
|
spin do
|
@@ -34,8 +41,7 @@ class SocketTest < MiniTest::Test
|
|
34
41
|
end
|
35
42
|
|
36
43
|
def test_read
|
37
|
-
port =
|
38
|
-
server = TCPServer.new('127.0.0.1', port)
|
44
|
+
port, server = start_tcp_server_on_random_port
|
39
45
|
server_fiber = spin do
|
40
46
|
while (socket = server.accept)
|
41
47
|
spin do
|
@@ -74,9 +80,7 @@ class SocketTest < MiniTest::Test
|
|
74
80
|
|
75
81
|
# sending multiple strings at once
|
76
82
|
def test_sendv
|
77
|
-
port =
|
78
|
-
server = TCPServer.new('127.0.0.1', port)
|
79
|
-
|
83
|
+
port, server = start_tcp_server_on_random_port
|
80
84
|
server_fiber = spin do
|
81
85
|
while (socket = server.accept)
|
82
86
|
spin do
|
@@ -100,9 +104,7 @@ class SocketTest < MiniTest::Test
|
|
100
104
|
|
101
105
|
|
102
106
|
def test_feed_loop
|
103
|
-
port =
|
104
|
-
server = TCPServer.new('127.0.0.1', port)
|
105
|
-
|
107
|
+
port, server = start_tcp_server_on_random_port
|
106
108
|
server_fiber = spin do
|
107
109
|
reader = MessagePack::Unpacker.new
|
108
110
|
while (socket = server.accept)
|
data/test/test_supervise.rb
CHANGED
@@ -135,6 +135,44 @@ class SuperviseTest < MiniTest::Test
|
|
135
135
|
assert_equal supervisor, f3.parent
|
136
136
|
end
|
137
137
|
|
138
|
+
def test_supervise_with_restart_true
|
139
|
+
buffer = []
|
140
|
+
f1 = spin(:f1) do
|
141
|
+
buffer << receive
|
142
|
+
rescue => e
|
143
|
+
buffer << e
|
144
|
+
e
|
145
|
+
end
|
146
|
+
supervisor = spin(:supervisor) { supervise(f1, restart: true) }
|
147
|
+
|
148
|
+
snooze
|
149
|
+
f1 << 'foo'
|
150
|
+
f1.await
|
151
|
+
snooze
|
152
|
+
assert_equal ['foo'], buffer
|
153
|
+
|
154
|
+
10.times { snooze }
|
155
|
+
|
156
|
+
assert_equal 1, supervisor.children.size
|
157
|
+
f2 = supervisor.children.first
|
158
|
+
assert f1 != f2
|
159
|
+
assert_equal :f1, f2.tag
|
160
|
+
assert_equal supervisor, f2.parent
|
161
|
+
|
162
|
+
e = RuntimeError.new('bar')
|
163
|
+
f2.raise(e)
|
164
|
+
f2.await rescue nil
|
165
|
+
3.times { snooze }
|
166
|
+
assert_equal ['foo', e], buffer
|
167
|
+
|
168
|
+
assert_equal 1, supervisor.children.size
|
169
|
+
f3 = supervisor.children.first
|
170
|
+
assert f2 != f3
|
171
|
+
assert f1 != f3
|
172
|
+
assert_equal :f1, f3.tag
|
173
|
+
assert_equal supervisor, f3.parent
|
174
|
+
end
|
175
|
+
|
138
176
|
def test_supervise_with_restart_on_error
|
139
177
|
buffer = []
|
140
178
|
f1 = spin(:f1) do
|
@@ -184,4 +222,51 @@ class SuperviseTest < MiniTest::Test
|
|
184
222
|
|
185
223
|
assert_equal [], buffer
|
186
224
|
end
|
225
|
+
|
226
|
+
def test_supervise_without_explicit_fibers
|
227
|
+
buffer = []
|
228
|
+
first = nil
|
229
|
+
supervisor = spin do
|
230
|
+
3.times do |i|
|
231
|
+
f = spin do
|
232
|
+
first = Fiber.current if i == 0
|
233
|
+
receive
|
234
|
+
buffer << i
|
235
|
+
end
|
236
|
+
end
|
237
|
+
Fiber.current.parent << :ok
|
238
|
+
supervise(restart: :always)
|
239
|
+
end
|
240
|
+
msg = receive
|
241
|
+
assert_equal :ok, msg
|
242
|
+
assert_equal 3, supervisor.children.size
|
243
|
+
|
244
|
+
sleep 0.1
|
245
|
+
assert_equal [], buffer
|
246
|
+
|
247
|
+
old_first = first
|
248
|
+
first << :foo
|
249
|
+
first = nil
|
250
|
+
snooze
|
251
|
+
assert_equal [0], buffer
|
252
|
+
|
253
|
+
snooze
|
254
|
+
assert_equal 3, supervisor.children.size
|
255
|
+
snooze
|
256
|
+
assert first
|
257
|
+
assert first != old_first
|
258
|
+
end
|
259
|
+
|
260
|
+
def test_supervise_with_added_fibers
|
261
|
+
buffer = []
|
262
|
+
supervisor = spin do
|
263
|
+
supervise { |f, r| buffer << [f, r] }
|
264
|
+
end
|
265
|
+
snooze
|
266
|
+
f1 = supervisor.spin { snooze; :foo }
|
267
|
+
f2 = supervisor.spin { snooze; :bar }
|
268
|
+
Fiber.await(f1, f2)
|
269
|
+
snooze
|
270
|
+
assert_equal [[f1, :foo], [f2, :bar]], buffer
|
271
|
+
end
|
187
272
|
end
|
data/test/test_sync.rb
CHANGED
data/test/test_thread.rb
CHANGED
@@ -180,7 +180,7 @@ class ThreadTest < MiniTest::Test
|
|
180
180
|
assert_equal count, GC.count
|
181
181
|
sleep 0.05
|
182
182
|
assert_equal count, GC.count
|
183
|
-
|
183
|
+
|
184
184
|
return unless IS_LINUX
|
185
185
|
|
186
186
|
# The idle tasks are ran at most once per fiber switch, before the backend
|
@@ -207,7 +207,7 @@ class ThreadTest < MiniTest::Test
|
|
207
207
|
counter = 0
|
208
208
|
|
209
209
|
Thread.current.on_idle { counter += 1 }
|
210
|
-
|
210
|
+
|
211
211
|
3.times { snooze }
|
212
212
|
assert_equal 0, counter
|
213
213
|
|
@@ -220,4 +220,24 @@ class ThreadTest < MiniTest::Test
|
|
220
220
|
3.times { snooze }
|
221
221
|
assert_equal 2, counter
|
222
222
|
end
|
223
|
+
|
224
|
+
def test_cross_thread_receive
|
225
|
+
buf = []
|
226
|
+
f = Fiber.current
|
227
|
+
t = Thread.new do
|
228
|
+
f << true
|
229
|
+
while (msg = receive)
|
230
|
+
buf << msg
|
231
|
+
end
|
232
|
+
end
|
233
|
+
|
234
|
+
receive # wait for thread to be ready
|
235
|
+
t << 1
|
236
|
+
t << 2
|
237
|
+
t << 3
|
238
|
+
t << nil
|
239
|
+
|
240
|
+
t.join
|
241
|
+
assert_equal [1, 2, 3], buf
|
242
|
+
end
|
223
243
|
end
|
data/test/test_thread_pool.rb
CHANGED
data/test/test_throttler.rb
CHANGED
data/test/test_timer.rb
CHANGED
@@ -137,11 +137,11 @@ class TimerMiscTest < MiniTest::Test
|
|
137
137
|
@timer = Polyphony::Timer.new(resolution: 0.001)
|
138
138
|
sleep 0
|
139
139
|
end
|
140
|
-
|
140
|
+
|
141
141
|
def teardown
|
142
142
|
@timer.stop
|
143
143
|
end
|
144
|
-
|
144
|
+
|
145
145
|
def test_timer_after
|
146
146
|
buffer = []
|
147
147
|
f = @timer.after(0.01) { buffer << 2 }
|