polyphony 0.66 → 0.70
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/CHANGELOG.md +23 -1
- data/Gemfile.lock +1 -1
- data/TODO.md +10 -63
- data/bin/pdbg +112 -0
- data/examples/core/await.rb +9 -1
- data/ext/polyphony/backend_common.c +32 -1
- data/ext/polyphony/backend_common.h +4 -1
- data/ext/polyphony/backend_io_uring.c +17 -5
- data/ext/polyphony/backend_libev.c +16 -0
- data/ext/polyphony/fiber.c +20 -0
- data/ext/polyphony/polyphony.c +2 -0
- data/ext/polyphony/polyphony.h +5 -2
- data/ext/polyphony/runqueue.c +4 -0
- data/ext/polyphony/runqueue.h +1 -0
- data/ext/polyphony/runqueue_ring_buffer.c +25 -14
- data/ext/polyphony/runqueue_ring_buffer.h +2 -0
- data/ext/polyphony/thread.c +2 -8
- data/lib/polyphony.rb +6 -0
- data/lib/polyphony/debugger.rb +225 -0
- data/lib/polyphony/extensions/debug.rb +1 -1
- data/lib/polyphony/extensions/fiber.rb +66 -69
- data/lib/polyphony/extensions/io.rb +1 -3
- data/lib/polyphony/extensions/openssl.rb +63 -1
- data/lib/polyphony/extensions/socket.rb +3 -3
- data/lib/polyphony/version.rb +1 -1
- data/test/helper.rb +4 -5
- data/test/stress.rb +6 -2
- data/test/test_fiber.rb +30 -11
- data/test/test_process_supervision.rb +38 -9
- data/test/test_supervise.rb +183 -100
- data/test/test_thread_pool.rb +1 -1
- data/test/test_throttler.rb +2 -2
- metadata +4 -2
@@ -6,7 +6,7 @@ class ProcessSupervisionTest < MiniTest::Test
|
|
6
6
|
def test_process_supervisor_with_block
|
7
7
|
i, o = IO.pipe
|
8
8
|
|
9
|
-
|
9
|
+
watcher = spin do
|
10
10
|
Polyphony.watch_process do
|
11
11
|
i.close
|
12
12
|
sleep 5
|
@@ -14,31 +14,60 @@ class ProcessSupervisionTest < MiniTest::Test
|
|
14
14
|
o << 'foo'
|
15
15
|
o.close
|
16
16
|
end
|
17
|
-
supervise(on_error: :restart)
|
18
17
|
end
|
19
18
|
|
19
|
+
supervisor = spin { supervise(watcher, restart: :always) }
|
20
|
+
|
20
21
|
sleep 0.05
|
21
|
-
|
22
|
-
|
22
|
+
supervisor.terminate
|
23
|
+
supervisor.await
|
23
24
|
|
24
25
|
o.close
|
25
26
|
msg = i.read
|
26
|
-
i.close
|
27
27
|
assert_equal 'foo', msg
|
28
28
|
end
|
29
29
|
|
30
|
+
def test_process_supervisor_restart_with_block
|
31
|
+
i1, o1 = IO.pipe
|
32
|
+
i2, o2 = IO.pipe
|
33
|
+
|
34
|
+
count = 0
|
35
|
+
watcher = spin do
|
36
|
+
count += 1
|
37
|
+
Polyphony.watch_process do
|
38
|
+
i1.gets
|
39
|
+
o2.puts count
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
supervisor = spin { supervise(watcher, restart: :always) }
|
44
|
+
|
45
|
+
o1.puts
|
46
|
+
l = i2.gets
|
47
|
+
assert_equal "1\n", l
|
48
|
+
|
49
|
+
o1.puts
|
50
|
+
l = i2.gets
|
51
|
+
assert_equal "2\n", l
|
52
|
+
|
53
|
+
o1.puts
|
54
|
+
l = i2.gets
|
55
|
+
assert_equal "3\n", l
|
56
|
+
end
|
57
|
+
|
30
58
|
def test_process_supervisor_with_cmd
|
31
59
|
fn = '/tmp/test_process_supervisor_with_cmd'
|
32
60
|
FileUtils.rm(fn) rescue nil
|
33
61
|
|
34
|
-
|
62
|
+
watcher = spin do
|
35
63
|
Polyphony.watch_process("echo foo >> #{fn}")
|
36
|
-
supervise(on_error: :restart)
|
37
64
|
end
|
38
65
|
|
66
|
+
supervisor = spin { supervise(watcher) }
|
67
|
+
|
39
68
|
sleep 0.05
|
40
|
-
|
41
|
-
|
69
|
+
supervisor.terminate
|
70
|
+
supervisor.await
|
42
71
|
|
43
72
|
assert_equal "foo\n", IO.read(fn)
|
44
73
|
|
data/test/test_supervise.rb
CHANGED
@@ -2,103 +2,186 @@
|
|
2
2
|
|
3
3
|
require_relative 'helper'
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
5
|
+
class SuperviseTest < MiniTest::Test
|
6
|
+
def test_supervise_with_block
|
7
|
+
buffer = []
|
8
|
+
f1 = spin(:f1) { receive }
|
9
|
+
f2 = spin(:f2) { receive }
|
10
|
+
supervisor = spin(:supervisor) { supervise(f1, f2) { |*args| buffer << args } }
|
11
|
+
|
12
|
+
snooze
|
13
|
+
f1 << 'foo'
|
14
|
+
f1.await
|
15
|
+
10.times { snooze }
|
16
|
+
assert_equal [[f1, 'foo']], buffer
|
17
|
+
|
18
|
+
f2 << 'bar'
|
19
|
+
f2.await
|
20
|
+
assert_equal [[f1, 'foo'], [f2, 'bar']], buffer
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_supervise_with_on_done
|
24
|
+
buffer = []
|
25
|
+
f1 = spin(:f1) { receive }
|
26
|
+
f2 = spin(:f2) { receive }
|
27
|
+
supervisor = spin(:supervisor) do
|
28
|
+
supervise(f1, f2, on_done: ->(*args) { buffer << args })
|
29
|
+
end
|
30
|
+
|
31
|
+
snooze
|
32
|
+
f1 << 'foo'
|
33
|
+
f1.await
|
34
|
+
10.times { snooze }
|
35
|
+
assert_equal [[f1, 'foo']], buffer
|
36
|
+
|
37
|
+
f2 << 'bar'
|
38
|
+
f2.await
|
39
|
+
assert_equal [[f1, 'foo'], [f2, 'bar']], buffer
|
40
|
+
end
|
41
|
+
|
42
|
+
def test_supervise_with_on_error
|
43
|
+
buffer = []
|
44
|
+
f1 = spin(:f1) { receive }
|
45
|
+
f2 = spin(:f2) { receive }
|
46
|
+
supervisor = spin(:supervisor) do
|
47
|
+
supervise(f1, f2, on_error: ->(*args) { buffer << args })
|
48
|
+
end
|
49
|
+
|
50
|
+
snooze
|
51
|
+
f1 << 'foo'
|
52
|
+
f1.await
|
53
|
+
10.times { snooze }
|
54
|
+
assert_equal [], buffer
|
55
|
+
|
56
|
+
e = RuntimeError.new('blah')
|
57
|
+
f2.raise(e)
|
58
|
+
3.times { snooze }
|
59
|
+
assert_equal [[f2, e]], buffer
|
60
|
+
end
|
61
|
+
|
62
|
+
def test_supervise_with_manual_restart
|
63
|
+
buffer = []
|
64
|
+
f1 = spin(:f1) { receive }
|
65
|
+
supervisor = spin(:supervisor) do
|
66
|
+
supervise(f1) do |f, r|
|
67
|
+
buffer << [f, r]
|
68
|
+
f.restart
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
snooze
|
73
|
+
f1 << 'foo'
|
74
|
+
f1.await
|
75
|
+
snooze
|
76
|
+
assert_equal [[f1, 'foo']], buffer
|
77
|
+
|
78
|
+
10.times { snooze }
|
79
|
+
|
80
|
+
assert_equal 1, supervisor.children.size
|
81
|
+
f2 = supervisor.children.first
|
82
|
+
assert f1 != f2
|
83
|
+
assert_equal :f1, f2.tag
|
84
|
+
assert_equal supervisor, f2.parent
|
85
|
+
|
86
|
+
e = RuntimeError.new('bar')
|
87
|
+
f2.raise(e)
|
88
|
+
f2.await rescue nil
|
89
|
+
3.times { snooze }
|
90
|
+
assert_equal [[f1, 'foo'], [f2, e]], buffer
|
91
|
+
|
92
|
+
assert_equal 1, supervisor.children.size
|
93
|
+
f3 = supervisor.children.first
|
94
|
+
assert f2 != f3
|
95
|
+
assert f1 != f3
|
96
|
+
assert_equal :f1, f3.tag
|
97
|
+
assert_equal supervisor, f3.parent
|
98
|
+
end
|
99
|
+
|
100
|
+
def test_supervise_with_restart_always
|
101
|
+
buffer = []
|
102
|
+
f1 = spin(:f1) do
|
103
|
+
buffer << receive
|
104
|
+
rescue => e
|
105
|
+
buffer << e
|
106
|
+
e
|
107
|
+
end
|
108
|
+
supervisor = spin(:supervisor) { supervise(f1, restart: :always) }
|
109
|
+
|
110
|
+
snooze
|
111
|
+
f1 << 'foo'
|
112
|
+
f1.await
|
113
|
+
snooze
|
114
|
+
assert_equal ['foo'], buffer
|
115
|
+
|
116
|
+
10.times { snooze }
|
117
|
+
|
118
|
+
assert_equal 1, supervisor.children.size
|
119
|
+
f2 = supervisor.children.first
|
120
|
+
assert f1 != f2
|
121
|
+
assert_equal :f1, f2.tag
|
122
|
+
assert_equal supervisor, f2.parent
|
123
|
+
|
124
|
+
e = RuntimeError.new('bar')
|
125
|
+
f2.raise(e)
|
126
|
+
f2.await rescue nil
|
127
|
+
3.times { snooze }
|
128
|
+
assert_equal ['foo', e], buffer
|
129
|
+
|
130
|
+
assert_equal 1, supervisor.children.size
|
131
|
+
f3 = supervisor.children.first
|
132
|
+
assert f2 != f3
|
133
|
+
assert f1 != f3
|
134
|
+
assert_equal :f1, f3.tag
|
135
|
+
assert_equal supervisor, f3.parent
|
136
|
+
end
|
137
|
+
|
138
|
+
def test_supervise_with_restart_on_error
|
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: :on_error) }
|
147
|
+
|
148
|
+
snooze
|
149
|
+
e = RuntimeError.new('bar')
|
150
|
+
f1.raise(e)
|
151
|
+
f1.await rescue nil
|
152
|
+
snooze
|
153
|
+
assert_equal [e], buffer
|
154
|
+
|
155
|
+
10.times { snooze }
|
156
|
+
|
157
|
+
assert_equal 1, supervisor.children.size
|
158
|
+
f2 = supervisor.children.first
|
159
|
+
assert f1 != f2
|
160
|
+
assert_equal :f1, f2.tag
|
161
|
+
assert_equal supervisor, f2.parent
|
162
|
+
|
163
|
+
f2 << 'foo'
|
164
|
+
f2.await rescue nil
|
165
|
+
3.times { snooze }
|
166
|
+
assert_equal [e, 'foo'], buffer
|
167
|
+
|
168
|
+
assert_equal 0, supervisor.children.size
|
169
|
+
end
|
170
|
+
|
171
|
+
def test_supervise_terminate
|
172
|
+
buffer = []
|
173
|
+
f1 = spin(:f1) do
|
174
|
+
buffer << receive
|
175
|
+
rescue => e
|
176
|
+
buffer << e
|
177
|
+
e
|
178
|
+
end
|
179
|
+
supervisor = spin(:supervisor) { supervise(f1, restart: :on_error) }
|
180
|
+
|
181
|
+
sleep 0.05
|
182
|
+
supervisor.terminate
|
183
|
+
supervisor.await
|
184
|
+
|
185
|
+
assert_equal [], buffer
|
186
|
+
end
|
187
|
+
end
|
data/test/test_thread_pool.rb
CHANGED
data/test/test_throttler.rb
CHANGED
@@ -10,7 +10,7 @@ class ThrottlerTest < MiniTest::Test
|
|
10
10
|
f = spin { loop { t.process { buffer << 1 } } }
|
11
11
|
sleep 0.2
|
12
12
|
f.stop
|
13
|
-
assert_in_range 1..
|
13
|
+
assert_in_range 1..4, buffer.size
|
14
14
|
ensure
|
15
15
|
t.stop
|
16
16
|
end
|
@@ -23,7 +23,7 @@ class ThrottlerTest < MiniTest::Test
|
|
23
23
|
end
|
24
24
|
sleep 0.25
|
25
25
|
f.stop
|
26
|
-
assert_in_range 2..
|
26
|
+
assert_in_range 2..7, buffer.size
|
27
27
|
ensure
|
28
28
|
t.stop
|
29
29
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: polyphony
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: '0.
|
4
|
+
version: '0.70'
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sharon Rosner
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-08-
|
11
|
+
date: 2021-08-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake-compiler
|
@@ -156,6 +156,7 @@ files:
|
|
156
156
|
- README.md
|
157
157
|
- Rakefile
|
158
158
|
- TODO.md
|
159
|
+
- bin/pdbg
|
159
160
|
- bin/polyphony-debug
|
160
161
|
- bin/stress.rb
|
161
162
|
- bin/test
|
@@ -356,6 +357,7 @@ files:
|
|
356
357
|
- lib/polyphony/core/thread_pool.rb
|
357
358
|
- lib/polyphony/core/throttler.rb
|
358
359
|
- lib/polyphony/core/timer.rb
|
360
|
+
- lib/polyphony/debugger.rb
|
359
361
|
- lib/polyphony/extensions/core.rb
|
360
362
|
- lib/polyphony/extensions/debug.rb
|
361
363
|
- lib/polyphony/extensions/fiber.rb
|