polyphony 0.43.11 → 0.45.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
- data/.rubocop.yml +8 -1
- data/CHANGELOG.md +40 -0
- data/Gemfile.lock +18 -8
- data/Rakefile +1 -1
- data/TODO.md +22 -9
- data/docs/_posts/2020-07-26-polyphony-0.44.md +77 -0
- data/docs/api-reference/thread.md +1 -1
- data/docs/getting-started/overview.md +14 -14
- data/docs/getting-started/tutorial.md +1 -1
- data/examples/adapters/redis_client.rb +3 -1
- data/examples/adapters/redis_pubsub_perf.rb +11 -8
- data/examples/adapters/sequel_mysql.rb +23 -0
- data/examples/adapters/sequel_mysql_pool.rb +33 -0
- data/examples/adapters/sequel_pg.rb +24 -0
- data/examples/core/{02-awaiting-fibers.rb → await.rb} +0 -0
- data/examples/core/{xx-channels.rb → channels.rb} +0 -0
- data/examples/core/deferring-an-operation.rb +16 -0
- data/examples/core/{xx-erlang-style-genserver.rb → erlang-style-genserver.rb} +16 -9
- data/examples/core/{xx-forking.rb → forking.rb} +1 -1
- data/examples/core/handling-signals.rb +11 -0
- data/examples/core/{03-interrupting.rb → interrupt.rb} +0 -0
- data/examples/core/{xx-pingpong.rb → pingpong.rb} +7 -5
- data/examples/core/{xx-recurrent-timer.rb → recurrent-timer.rb} +1 -1
- data/examples/core/{xx-resource_delegate.rb → resource_delegate.rb} +3 -4
- data/examples/core/{01-spinning-up-fibers.rb → spin.rb} +1 -1
- data/examples/core/{xx-spin_error_backtrace.rb → spin_error_backtrace.rb} +1 -1
- data/examples/core/{xx-supervise-process.rb → supervise-process.rb} +8 -5
- data/examples/core/supervisor.rb +20 -0
- data/examples/core/{xx-thread-sleep.rb → thread-sleep.rb} +0 -0
- data/examples/core/{xx-thread_pool.rb → thread_pool.rb} +0 -0
- data/examples/core/{xx-throttling.rb → throttling.rb} +0 -0
- data/examples/core/{xx-timeout.rb → timeout.rb} +0 -0
- data/examples/core/{xx-using-a-mutex.rb → using-a-mutex.rb} +0 -0
- data/examples/core/{xx-worker-thread.rb → worker-thread.rb} +2 -2
- data/examples/io/{xx-backticks.rb → backticks.rb} +0 -0
- data/examples/io/{xx-echo_client.rb → echo_client.rb} +1 -1
- data/examples/io/{xx-echo_client_from_stdin.rb → echo_client_from_stdin.rb} +2 -2
- data/examples/io/{xx-echo_pipe.rb → echo_pipe.rb} +1 -1
- data/examples/io/{xx-echo_server.rb → echo_server.rb} +0 -0
- data/examples/io/{xx-echo_server_with_timeout.rb → echo_server_with_timeout.rb} +1 -1
- data/examples/io/{xx-echo_stdin.rb → echo_stdin.rb} +0 -0
- data/examples/io/{xx-happy-eyeballs.rb → happy-eyeballs.rb} +0 -0
- data/examples/io/{xx-httparty.rb → httparty.rb} +4 -13
- data/examples/io/{xx-irb.rb → irb.rb} +0 -0
- data/examples/io/{xx-net-http.rb → net-http.rb} +0 -0
- data/examples/io/{xx-open.rb → open.rb} +0 -0
- data/examples/io/pry.rb +18 -0
- data/examples/io/rack_server.rb +71 -0
- data/examples/io/raw.rb +14 -0
- data/examples/io/reline.rb +18 -0
- data/examples/io/{xx-system.rb → system.rb} +1 -1
- data/examples/io/{xx-tcpserver.rb → tcpserver.rb} +0 -0
- data/examples/io/{xx-tcpsocket.rb → tcpsocket.rb} +0 -0
- data/examples/io/tunnel.rb +6 -1
- data/examples/io/{xx-zip.rb → zip.rb} +0 -0
- data/examples/performance/fiber_transfer.rb +2 -1
- data/examples/performance/fs_read.rb +5 -6
- data/examples/{io/xx-switch.rb → performance/switch.rb} +2 -1
- data/examples/performance/thread-vs-fiber/{xx-httparty_multi.rb → httparty_multi.rb} +3 -4
- data/examples/performance/thread-vs-fiber/{xx-httparty_threaded.rb → httparty_threaded.rb} +0 -0
- data/examples/performance/thread-vs-fiber/polyphony_mt_server.rb +1 -1
- data/examples/performance/thread-vs-fiber/polyphony_server.rb +1 -1
- data/examples/performance/thread-vs-fiber/polyphony_server_read_loop.rb +1 -1
- data/examples/performance/thread-vs-fiber/threaded_server.rb +1 -5
- data/examples/performance/thread_pool_perf.rb +6 -7
- data/ext/polyphony/backend.h +40 -0
- data/ext/polyphony/event.c +3 -3
- data/ext/polyphony/extconf.rb +1 -1
- data/ext/polyphony/fiber.c +66 -6
- data/ext/polyphony/{libev_agent.c → libev_backend.c} +237 -238
- data/ext/polyphony/polyphony.c +3 -3
- data/ext/polyphony/polyphony.h +15 -20
- data/ext/polyphony/polyphony_ext.c +3 -4
- data/ext/polyphony/queue.c +5 -6
- data/ext/polyphony/ring_buffer.c +0 -1
- data/ext/polyphony/thread.c +36 -33
- data/lib/polyphony.rb +26 -39
- data/lib/polyphony/adapters/fs.rb +1 -1
- data/lib/polyphony/adapters/irb.rb +2 -17
- data/lib/polyphony/adapters/mysql2.rb +19 -0
- data/lib/polyphony/adapters/postgres.rb +5 -5
- data/lib/polyphony/adapters/process.rb +2 -5
- data/lib/polyphony/adapters/readline.rb +17 -0
- data/lib/polyphony/adapters/redis.rb +1 -1
- data/lib/polyphony/adapters/sequel.rb +45 -0
- data/lib/polyphony/core/exceptions.rb +11 -0
- data/lib/polyphony/core/global_api.rb +17 -12
- data/lib/polyphony/core/resource_pool.rb +20 -7
- data/lib/polyphony/core/sync.rb +46 -8
- data/lib/polyphony/core/throttler.rb +1 -1
- data/lib/polyphony/extensions/core.rb +30 -30
- data/lib/polyphony/extensions/fiber.rb +30 -49
- data/lib/polyphony/extensions/io.rb +60 -16
- data/lib/polyphony/extensions/openssl.rb +6 -6
- data/lib/polyphony/extensions/socket.rb +14 -15
- data/lib/polyphony/extensions/thread.rb +6 -5
- data/lib/polyphony/version.rb +1 -1
- data/polyphony.gemspec +7 -3
- data/test/helper.rb +1 -1
- data/test/{test_agent.rb → test_backend.rb} +22 -22
- data/test/test_fiber.rb +29 -12
- data/test/test_io.rb +59 -1
- data/test/test_kernel.rb +5 -0
- data/test/test_resource_pool.rb +29 -4
- data/test/test_signal.rb +16 -37
- data/test/test_socket.rb +17 -0
- data/test/test_sync.rb +52 -0
- metadata +127 -97
- data/.gitbook.yaml +0 -4
- data/examples/adapters/concurrent-ruby.rb +0 -9
- data/examples/core/04-handling-signals.rb +0 -19
- data/examples/core/xx-agent.rb +0 -102
- data/examples/core/xx-at_exit.rb +0 -29
- data/examples/core/xx-caller.rb +0 -12
- data/examples/core/xx-daemon.rb +0 -14
- data/examples/core/xx-deadlock.rb +0 -8
- data/examples/core/xx-deferring-an-operation.rb +0 -14
- data/examples/core/xx-exception-backtrace.rb +0 -40
- data/examples/core/xx-fork-cleanup.rb +0 -22
- data/examples/core/xx-fork-spin.rb +0 -42
- data/examples/core/xx-fork-terminate.rb +0 -27
- data/examples/core/xx-move_on.rb +0 -23
- data/examples/core/xx-queue-async.rb +0 -120
- data/examples/core/xx-readpartial.rb +0 -18
- data/examples/core/xx-signals.rb +0 -16
- data/examples/core/xx-sleep-forever.rb +0 -9
- data/examples/core/xx-sleeping.rb +0 -25
- data/examples/core/xx-snooze-starve.rb +0 -16
- data/examples/core/xx-spin-fork.rb +0 -49
- data/examples/core/xx-state-machine.rb +0 -51
- data/examples/core/xx-stop.rb +0 -20
- data/examples/core/xx-supervisors.rb +0 -21
- data/examples/core/xx-thread-selector-sleep.rb +0 -51
- data/examples/core/xx-thread-selector-snooze.rb +0 -46
- data/examples/core/xx-thread-snooze.rb +0 -34
- data/examples/core/xx-timer-gc.rb +0 -17
- data/examples/core/xx-trace.rb +0 -79
- data/examples/performance/xx-array.rb +0 -11
- data/examples/performance/xx-fiber-switch.rb +0 -9
- data/examples/performance/xx-snooze.rb +0 -15
- data/examples/xx-spin.rb +0 -32
- data/ext/polyphony/agent.h +0 -41
data/test/helper.rb
CHANGED
|
@@ -31,7 +31,7 @@ class MiniTest::Test
|
|
|
31
31
|
end
|
|
32
32
|
Fiber.current.setup_main_fiber
|
|
33
33
|
Fiber.current.instance_variable_set(:@auto_watcher, nil)
|
|
34
|
-
Thread.current.
|
|
34
|
+
Thread.current.backend = Polyphony::Backend.new
|
|
35
35
|
sleep 0 # apparently this helps with timer accuracy
|
|
36
36
|
end
|
|
37
37
|
|
|
@@ -2,39 +2,39 @@
|
|
|
2
2
|
|
|
3
3
|
require_relative 'helper'
|
|
4
4
|
|
|
5
|
-
class
|
|
5
|
+
class BackendTest < MiniTest::Test
|
|
6
6
|
def setup
|
|
7
7
|
super
|
|
8
|
-
@
|
|
9
|
-
@
|
|
10
|
-
Thread.current.
|
|
8
|
+
@prev_backend = Thread.current.backend
|
|
9
|
+
@backend = Polyphony::Backend.new
|
|
10
|
+
Thread.current.backend = @backend
|
|
11
11
|
end
|
|
12
12
|
|
|
13
13
|
def teardown
|
|
14
|
-
@
|
|
15
|
-
Thread.current.
|
|
14
|
+
@backend.finalize
|
|
15
|
+
Thread.current.backend = @prev_backend
|
|
16
16
|
end
|
|
17
17
|
|
|
18
18
|
def test_sleep
|
|
19
19
|
count = 0
|
|
20
20
|
t0 = Time.now
|
|
21
21
|
spin {
|
|
22
|
-
@
|
|
22
|
+
@backend.sleep 0.01
|
|
23
23
|
count += 1
|
|
24
|
-
@
|
|
24
|
+
@backend.sleep 0.01
|
|
25
25
|
count += 1
|
|
26
|
-
@
|
|
26
|
+
@backend.sleep 0.01
|
|
27
27
|
count += 1
|
|
28
28
|
}.await
|
|
29
|
-
|
|
29
|
+
assert_in_delta 0.03, Time.now - t0, 0.005
|
|
30
30
|
assert_equal 3, count
|
|
31
31
|
end
|
|
32
32
|
|
|
33
33
|
def test_write_read_partial
|
|
34
34
|
i, o = IO.pipe
|
|
35
35
|
buf = +''
|
|
36
|
-
f = spin { @
|
|
37
|
-
@
|
|
36
|
+
f = spin { @backend.read(i, buf, 5, false) }
|
|
37
|
+
@backend.write(o, 'Hello world')
|
|
38
38
|
return_value = f.await
|
|
39
39
|
|
|
40
40
|
assert_equal 'Hello', buf
|
|
@@ -44,10 +44,10 @@ class AgentTest < MiniTest::Test
|
|
|
44
44
|
def test_write_read_to_eof_limited_buffer
|
|
45
45
|
i, o = IO.pipe
|
|
46
46
|
buf = +''
|
|
47
|
-
f = spin { @
|
|
48
|
-
@
|
|
47
|
+
f = spin { @backend.read(i, buf, 5, true) }
|
|
48
|
+
@backend.write(o, 'Hello')
|
|
49
49
|
snooze
|
|
50
|
-
@
|
|
50
|
+
@backend.write(o, ' world')
|
|
51
51
|
snooze
|
|
52
52
|
o.close
|
|
53
53
|
return_value = f.await
|
|
@@ -59,10 +59,10 @@ class AgentTest < MiniTest::Test
|
|
|
59
59
|
def test_write_read_to_eof
|
|
60
60
|
i, o = IO.pipe
|
|
61
61
|
buf = +''
|
|
62
|
-
f = spin { @
|
|
63
|
-
@
|
|
62
|
+
f = spin { @backend.read(i, buf, 10**6, true) }
|
|
63
|
+
@backend.write(o, 'Hello')
|
|
64
64
|
snooze
|
|
65
|
-
@
|
|
65
|
+
@backend.write(o, ' world')
|
|
66
66
|
snooze
|
|
67
67
|
o.close
|
|
68
68
|
return_value = f.await
|
|
@@ -73,11 +73,11 @@ class AgentTest < MiniTest::Test
|
|
|
73
73
|
|
|
74
74
|
def test_waitpid
|
|
75
75
|
pid = fork do
|
|
76
|
-
@
|
|
76
|
+
@backend.post_fork
|
|
77
77
|
exit(42)
|
|
78
78
|
end
|
|
79
79
|
|
|
80
|
-
result = @
|
|
80
|
+
result = @backend.waitpid(pid)
|
|
81
81
|
assert_equal [pid, 42], result
|
|
82
82
|
end
|
|
83
83
|
|
|
@@ -87,7 +87,7 @@ class AgentTest < MiniTest::Test
|
|
|
87
87
|
buf = []
|
|
88
88
|
spin do
|
|
89
89
|
buf << :ready
|
|
90
|
-
@
|
|
90
|
+
@backend.read_loop(i) { |d| buf << d }
|
|
91
91
|
buf << :done
|
|
92
92
|
end
|
|
93
93
|
|
|
@@ -107,7 +107,7 @@ class AgentTest < MiniTest::Test
|
|
|
107
107
|
|
|
108
108
|
clients = []
|
|
109
109
|
server_fiber = spin do
|
|
110
|
-
@
|
|
110
|
+
@backend.accept_loop(server) { |c| clients << c }
|
|
111
111
|
end
|
|
112
112
|
|
|
113
113
|
c1 = TCPSocket.new('127.0.0.1', 1234)
|
data/test/test_fiber.rb
CHANGED
|
@@ -352,7 +352,7 @@ class FiberTest < MiniTest::Test
|
|
|
352
352
|
result = []
|
|
353
353
|
f = Fiber.current.spin do
|
|
354
354
|
result << :start
|
|
355
|
-
result << Thread.current.
|
|
355
|
+
result << Thread.current.backend.sleep(1)
|
|
356
356
|
end
|
|
357
357
|
snooze
|
|
358
358
|
f.interrupt
|
|
@@ -413,6 +413,22 @@ class FiberTest < MiniTest::Test
|
|
|
413
413
|
f2&.stop
|
|
414
414
|
end
|
|
415
415
|
|
|
416
|
+
def test_interject
|
|
417
|
+
buf = []
|
|
418
|
+
f = spin_loop { sleep }
|
|
419
|
+
snooze
|
|
420
|
+
f.interject { buf << Fiber.current }
|
|
421
|
+
snooze
|
|
422
|
+
assert_equal [f], buf
|
|
423
|
+
assert_equal :waiting, f.state
|
|
424
|
+
|
|
425
|
+
f.interject { buf << :foo; raise Polyphony::MoveOn }
|
|
426
|
+
snooze
|
|
427
|
+
|
|
428
|
+
assert_equal [f, :foo], buf
|
|
429
|
+
assert_equal :dead, f.state
|
|
430
|
+
end
|
|
431
|
+
|
|
416
432
|
def test_state
|
|
417
433
|
counter = 0
|
|
418
434
|
f = spin do
|
|
@@ -625,7 +641,7 @@ class FiberTest < MiniTest::Test
|
|
|
625
641
|
end
|
|
626
642
|
end
|
|
627
643
|
sleep 0.1
|
|
628
|
-
f = spin { Thread.current.
|
|
644
|
+
f = spin { Thread.current.backend.waitpid(pid) }
|
|
629
645
|
o.close
|
|
630
646
|
Process.kill('INT', pid)
|
|
631
647
|
f.await
|
|
@@ -647,7 +663,7 @@ class FiberTest < MiniTest::Test
|
|
|
647
663
|
end
|
|
648
664
|
end
|
|
649
665
|
sleep 0.2
|
|
650
|
-
f = spin { Thread.current.
|
|
666
|
+
f = spin { Thread.current.backend.waitpid(pid) }
|
|
651
667
|
o.close
|
|
652
668
|
Process.kill('TERM', pid)
|
|
653
669
|
f.await
|
|
@@ -674,7 +690,7 @@ class FiberTest < MiniTest::Test
|
|
|
674
690
|
sleep 0.2
|
|
675
691
|
Process.kill('TERM', pid)
|
|
676
692
|
end
|
|
677
|
-
Thread.current.
|
|
693
|
+
Thread.current.backend.waitpid(pid)
|
|
678
694
|
klass = i.read
|
|
679
695
|
i.close
|
|
680
696
|
assert_equal 'Polyphony::Terminate', klass
|
|
@@ -684,15 +700,16 @@ class FiberTest < MiniTest::Test
|
|
|
684
700
|
buffer = []
|
|
685
701
|
f = Fiber.new { buffer << receive }
|
|
686
702
|
|
|
687
|
-
|
|
703
|
+
assert_nil f.thread
|
|
688
704
|
snooze
|
|
689
705
|
f.setup_raw
|
|
690
706
|
assert_equal Thread.current, f.thread
|
|
691
707
|
assert_nil f.parent
|
|
692
708
|
|
|
693
709
|
f.schedule
|
|
710
|
+
snooze
|
|
694
711
|
f << 'bar'
|
|
695
|
-
|
|
712
|
+
snooze
|
|
696
713
|
assert_equal ['bar'], buffer
|
|
697
714
|
end
|
|
698
715
|
end
|
|
@@ -795,20 +812,20 @@ class MailboxTest < MiniTest::Test
|
|
|
795
812
|
assert_equal ['foo'] * 100, messages
|
|
796
813
|
end
|
|
797
814
|
|
|
798
|
-
def
|
|
799
|
-
assert_equal [],
|
|
815
|
+
def test_receive_all_pending
|
|
816
|
+
assert_equal [], receive_all_pending
|
|
800
817
|
|
|
801
818
|
(1..5).each { |i| Fiber.current << i }
|
|
802
|
-
assert_equal (1..5).to_a,
|
|
803
|
-
assert_equal [],
|
|
819
|
+
assert_equal (1..5).to_a, receive_all_pending
|
|
820
|
+
assert_equal [], receive_all_pending
|
|
804
821
|
end
|
|
805
822
|
|
|
806
|
-
def
|
|
823
|
+
def test_receive_all_pending_on_termination
|
|
807
824
|
buffer = []
|
|
808
825
|
worker = spin do
|
|
809
826
|
loop { buffer << receive }
|
|
810
827
|
rescue Polyphony::Terminate
|
|
811
|
-
|
|
828
|
+
receive_all_pending.each { |r| buffer << r }
|
|
812
829
|
end
|
|
813
830
|
|
|
814
831
|
worker << 1
|
data/test/test_io.rb
CHANGED
|
@@ -55,7 +55,7 @@ class IOTest < MiniTest::Test
|
|
|
55
55
|
results << result
|
|
56
56
|
case result
|
|
57
57
|
when :wait_readable
|
|
58
|
-
Thread.current.
|
|
58
|
+
Thread.current.backend.wait_io(i, false)
|
|
59
59
|
else
|
|
60
60
|
break result
|
|
61
61
|
end
|
|
@@ -92,6 +92,48 @@ class IOTest < MiniTest::Test
|
|
|
92
92
|
assert_raises(EOFError) { i.readpartial(1) }
|
|
93
93
|
end
|
|
94
94
|
|
|
95
|
+
def test_getc
|
|
96
|
+
i, o = IO.pipe
|
|
97
|
+
|
|
98
|
+
buf = []
|
|
99
|
+
f = spin do
|
|
100
|
+
while (c = i.getc)
|
|
101
|
+
buf << c
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
snooze
|
|
106
|
+
assert_equal [], buf
|
|
107
|
+
|
|
108
|
+
o << 'f'
|
|
109
|
+
snooze
|
|
110
|
+
o << 'g'
|
|
111
|
+
o.close
|
|
112
|
+
f.await
|
|
113
|
+
assert_equal ['f', 'g'], buf
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def test_getbyte
|
|
117
|
+
i, o = IO.pipe
|
|
118
|
+
|
|
119
|
+
buf = []
|
|
120
|
+
f = spin do
|
|
121
|
+
while (b = i.getbyte)
|
|
122
|
+
buf << b
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
snooze
|
|
127
|
+
assert_equal [], buf
|
|
128
|
+
|
|
129
|
+
o << 'f'
|
|
130
|
+
snooze
|
|
131
|
+
o << 'g'
|
|
132
|
+
o.close
|
|
133
|
+
f.await
|
|
134
|
+
assert_equal [102, 103], buf
|
|
135
|
+
end
|
|
136
|
+
|
|
95
137
|
# see https://github.com/digital-fabric/polyphony/issues/30
|
|
96
138
|
def test_reopened_tempfile
|
|
97
139
|
file = Tempfile.new
|
|
@@ -246,4 +288,20 @@ class IOClassMethodsTest < MiniTest::Test
|
|
|
246
288
|
assert_equal 1e6, s.bytesize
|
|
247
289
|
assert s == IO.orig_read(fn)
|
|
248
290
|
end
|
|
291
|
+
|
|
292
|
+
def pipe_read
|
|
293
|
+
i, o = IO.pipe
|
|
294
|
+
yield o
|
|
295
|
+
o.close
|
|
296
|
+
i.read
|
|
297
|
+
ensure
|
|
298
|
+
i.close
|
|
299
|
+
end
|
|
300
|
+
|
|
301
|
+
def test_puts
|
|
302
|
+
assert_equal "foo\n", pipe_read { |f| f.puts 'foo' }
|
|
303
|
+
assert_equal "foo\n", pipe_read { |f| f.puts "foo\n" }
|
|
304
|
+
assert_equal "foo\nbar\n", pipe_read { |f| f.puts 'foo', 'bar' }
|
|
305
|
+
assert_equal "foo\nbar\n", pipe_read { |f| f.puts 'foo', "bar\n" }
|
|
306
|
+
end
|
|
249
307
|
end
|
data/test/test_kernel.rb
CHANGED
|
@@ -19,6 +19,11 @@ class KernelTest < MiniTest::Test
|
|
|
19
19
|
timer&.stop
|
|
20
20
|
end
|
|
21
21
|
|
|
22
|
+
def test_Kernel_system_singleton_method
|
|
23
|
+
assert_equal true, Kernel.system("which ruby > /dev/null 2>&1")
|
|
24
|
+
assert_equal false, Kernel.system("which rruubbyy > /dev/null 2>&1")
|
|
25
|
+
end
|
|
26
|
+
|
|
22
27
|
def patch_open3
|
|
23
28
|
class << Open3
|
|
24
29
|
alias_method :orig_popen2, :popen2
|
data/test/test_resource_pool.rb
CHANGED
|
@@ -27,6 +27,27 @@ class ResourcePoolTest < MiniTest::Test
|
|
|
27
27
|
assert_equal ['a', 'b', 'a', 'b'], results
|
|
28
28
|
end
|
|
29
29
|
|
|
30
|
+
def test_discard
|
|
31
|
+
resources = [+'a', +'b']
|
|
32
|
+
pool = Polyphony::ResourcePool.new(limit: 2) { resources.shift }
|
|
33
|
+
|
|
34
|
+
results = []
|
|
35
|
+
4.times {
|
|
36
|
+
spin {
|
|
37
|
+
snooze
|
|
38
|
+
pool.acquire { |resource|
|
|
39
|
+
results << resource
|
|
40
|
+
pool.discard! if resource == 'b'
|
|
41
|
+
snooze
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
Fiber.current.await_all_children
|
|
46
|
+
|
|
47
|
+
assert_equal ['a', 'b', 'a', 'a'], results
|
|
48
|
+
assert_equal 1, pool.size
|
|
49
|
+
end
|
|
50
|
+
|
|
30
51
|
def test_single_resource_limit
|
|
31
52
|
resources = [+'a', +'b']
|
|
32
53
|
pool = Polyphony::ResourcePool.new(limit: 1) { resources.shift }
|
|
@@ -41,7 +62,7 @@ class ResourcePoolTest < MiniTest::Test
|
|
|
41
62
|
}
|
|
42
63
|
}
|
|
43
64
|
}
|
|
44
|
-
|
|
65
|
+
Fiber.current.await_all_children
|
|
45
66
|
|
|
46
67
|
assert_equal ['a'] * 10, results
|
|
47
68
|
end
|
|
@@ -75,12 +96,16 @@ class ResourcePoolTest < MiniTest::Test
|
|
|
75
96
|
resources = [+'a', +'b']
|
|
76
97
|
pool = Polyphony::ResourcePool.new(limit: 1) { resources.shift }
|
|
77
98
|
|
|
99
|
+
results = []
|
|
78
100
|
pool.acquire do |r|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
101
|
+
results << r
|
|
102
|
+
2.times do
|
|
103
|
+
pool.acquire do |r|
|
|
104
|
+
results << r
|
|
105
|
+
end
|
|
82
106
|
end
|
|
83
107
|
end
|
|
108
|
+
assert_equal ['a']*3, results
|
|
84
109
|
end
|
|
85
110
|
|
|
86
111
|
def test_overloaded_resource_pool
|
data/test/test_signal.rb
CHANGED
|
@@ -3,18 +3,21 @@
|
|
|
3
3
|
require_relative 'helper'
|
|
4
4
|
|
|
5
5
|
class SignalTrapTest < Minitest::Test
|
|
6
|
+
def test_int_signal
|
|
7
|
+
Thread.new { sleep 0.001; Process.kill('INT', Process.pid) }
|
|
8
|
+
assert_raises(Interrupt) { sleep 5 }
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def test_term_signal
|
|
12
|
+
Thread.new { sleep 0.001; Process.kill('TERM', Process.pid) }
|
|
13
|
+
assert_raises(SystemExit) { sleep 5 }
|
|
14
|
+
end
|
|
15
|
+
|
|
6
16
|
def test_signal_exception_handling
|
|
7
17
|
i, o = IO.pipe
|
|
8
18
|
pid = Polyphony.fork do
|
|
9
19
|
i.close
|
|
10
|
-
|
|
11
|
-
spin do
|
|
12
|
-
sleep 5
|
|
13
|
-
rescue ::Interrupt => e
|
|
14
|
-
# the signal should be raised only in the main fiber
|
|
15
|
-
o.puts "1-interrupt"
|
|
16
|
-
end.await
|
|
17
|
-
end.await
|
|
20
|
+
sleep 5
|
|
18
21
|
rescue ::Interrupt => e
|
|
19
22
|
o.puts "3-interrupt"
|
|
20
23
|
ensure
|
|
@@ -23,7 +26,7 @@ class SignalTrapTest < Minitest::Test
|
|
|
23
26
|
sleep 0.01
|
|
24
27
|
o.close
|
|
25
28
|
Process.kill('INT', pid)
|
|
26
|
-
Thread.current.
|
|
29
|
+
Thread.current.backend.waitpid(pid)
|
|
27
30
|
buffer = i.read
|
|
28
31
|
assert_equal "3-interrupt\n", buffer
|
|
29
32
|
end
|
|
@@ -51,40 +54,16 @@ class SignalTrapTest < Minitest::Test
|
|
|
51
54
|
sleep 0.02
|
|
52
55
|
o.close
|
|
53
56
|
Process.kill('INT', pid)
|
|
54
|
-
Thread.current.
|
|
57
|
+
Thread.current.backend.waitpid(pid)
|
|
55
58
|
buffer = i.read
|
|
56
59
|
assert_equal "3 - interrupted\n2 - terminated\n1 - terminated\n", buffer
|
|
57
60
|
end
|
|
58
61
|
|
|
59
|
-
def
|
|
62
|
+
def test_interrupt_signal_scheduling
|
|
60
63
|
i, o = IO.pipe
|
|
61
64
|
pid = Polyphony.fork do
|
|
62
65
|
i.close
|
|
63
|
-
|
|
64
|
-
f2 = spin do
|
|
65
|
-
# this fiber will try to create a race condition by
|
|
66
|
-
# - being scheduled before f1 is scheduled with the Interrupt exception
|
|
67
|
-
# - scheduling f1 without an exception
|
|
68
|
-
suspend
|
|
69
|
-
f1.schedule
|
|
70
|
-
rescue ::Interrupt => e
|
|
71
|
-
o.puts '2-interrupt'
|
|
72
|
-
raise e
|
|
73
|
-
end
|
|
74
|
-
f1 = spin do
|
|
75
|
-
# this fiber is the one that will be current when the
|
|
76
|
-
# signal is trapped
|
|
77
|
-
sleep 1
|
|
78
|
-
o << 'boom'
|
|
79
|
-
rescue ::Interrupt => e
|
|
80
|
-
o.puts '1-interrupt'
|
|
81
|
-
raise e
|
|
82
|
-
end
|
|
83
|
-
old_trap = trap('INT') do
|
|
84
|
-
f2.schedule
|
|
85
|
-
old_trap.()
|
|
86
|
-
end
|
|
87
|
-
Fiber.current.await_all_children
|
|
66
|
+
sleep
|
|
88
67
|
rescue ::Interrupt => e
|
|
89
68
|
o.puts '3-interrupt'
|
|
90
69
|
ensure
|
|
@@ -93,7 +72,7 @@ class SignalTrapTest < Minitest::Test
|
|
|
93
72
|
o.close
|
|
94
73
|
sleep 0.1
|
|
95
74
|
Process.kill('INT', pid)
|
|
96
|
-
Thread.current.
|
|
75
|
+
Thread.current.backend.waitpid(pid)
|
|
97
76
|
buffer = i.read
|
|
98
77
|
assert_equal "3-interrupt\n", buffer
|
|
99
78
|
end
|