polyphony 0.75 → 0.79
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 +16 -0
- data/Gemfile.lock +1 -1
- data/examples/core/pingpong.rb +7 -4
- data/examples/core/trap1.rb +21 -0
- data/examples/core/trap2.rb +14 -0
- data/ext/polyphony/backend_common.c +14 -7
- data/ext/polyphony/backend_common.h +1 -1
- data/ext/polyphony/backend_io_uring.c +52 -32
- data/ext/polyphony/backend_libev.c +38 -17
- data/ext/polyphony/fiber.c +28 -28
- data/ext/polyphony/polyphony.c +5 -12
- data/ext/polyphony/polyphony.h +12 -9
- data/ext/polyphony/queue.c +82 -6
- data/ext/polyphony/thread.c +6 -2
- data/ext/test_eintr.c +50 -0
- data/lib/polyphony/core/debug.rb +146 -0
- data/lib/polyphony/extensions/fiber.rb +16 -8
- data/lib/polyphony/version.rb +1 -1
- data/test/helper.rb +2 -1
- data/test/stress.rb +1 -1
- data/test/test_fiber.rb +6 -4
- data/test/test_io.rb +7 -7
- data/test/test_queue.rb +103 -1
- data/test/test_signal.rb +57 -0
- data/test/test_supervise.rb +27 -0
- data/test/test_thread.rb +1 -1
- data/test/test_timer.rb +1 -1
- data/test/test_trace.rb +102 -24
- metadata +10 -7
data/test/test_signal.rb
CHANGED
@@ -3,6 +3,63 @@
|
|
3
3
|
require_relative 'helper'
|
4
4
|
|
5
5
|
class SignalTrapTest < Minitest::Test
|
6
|
+
def test_signal_handler_trace
|
7
|
+
i1, o1 = IO.pipe
|
8
|
+
i2, o2 = IO.pipe
|
9
|
+
pid = Process.pid
|
10
|
+
child_pid = Polyphony.fork do
|
11
|
+
i1.gets
|
12
|
+
Process.kill('SIGINT', pid)
|
13
|
+
sleep 0.1
|
14
|
+
o2.puts "done"
|
15
|
+
o2.close
|
16
|
+
end
|
17
|
+
|
18
|
+
events = []
|
19
|
+
begin
|
20
|
+
Thread.backend.trace_proc = proc { |*e| events << [e[0], e[1].tag] }
|
21
|
+
trap ('SIGINT') { }
|
22
|
+
|
23
|
+
o1.orig_write("\n")
|
24
|
+
o1.close
|
25
|
+
|
26
|
+
msg = i2.gets
|
27
|
+
assert_equal "done\n", msg
|
28
|
+
ensure
|
29
|
+
Thread.backend.trace_proc = nil
|
30
|
+
trap ('SIGINT') { raise Interrupt }
|
31
|
+
end
|
32
|
+
|
33
|
+
Fiber.current.tag = :main
|
34
|
+
|
35
|
+
expected = [
|
36
|
+
[:block, :main],
|
37
|
+
[:enter_poll, :main],
|
38
|
+
[:spin, :oob],
|
39
|
+
[:schedule, :oob],
|
40
|
+
[:leave_poll, :main],
|
41
|
+
[:unblock, :oob],
|
42
|
+
[:terminate, :oob],
|
43
|
+
[:block, :oob],
|
44
|
+
[:enter_poll, :oob],
|
45
|
+
[:schedule, :main],
|
46
|
+
[:leave_poll, :oob],
|
47
|
+
[:unblock, :main]
|
48
|
+
]
|
49
|
+
if Thread.backend.kind == :libev
|
50
|
+
expected += [
|
51
|
+
[:schedule, :main],
|
52
|
+
[:block, :main],
|
53
|
+
[:unblock, :main]
|
54
|
+
]
|
55
|
+
end
|
56
|
+
|
57
|
+
assert_equal expected, events
|
58
|
+
ensure
|
59
|
+
Process.kill('SIGTERM', child_pid) rescue nil
|
60
|
+
Process.wait(child_pid) rescue nil
|
61
|
+
end
|
62
|
+
|
6
63
|
def test_int_signal
|
7
64
|
Thread.new { sleep 0.001; Process.kill('INT', Process.pid) }
|
8
65
|
assert_raises(Interrupt) { sleep 5 }
|
data/test/test_supervise.rb
CHANGED
@@ -269,4 +269,31 @@ class SuperviseTest < MiniTest::Test
|
|
269
269
|
snooze
|
270
270
|
assert_equal [[f1, :foo], [f2, :bar]], buffer
|
271
271
|
end
|
272
|
+
|
273
|
+
def test_detached_supervisor
|
274
|
+
buffer = []
|
275
|
+
|
276
|
+
s = nil
|
277
|
+
f = spin {
|
278
|
+
foo = spin do
|
279
|
+
sleep 0.1
|
280
|
+
ensure
|
281
|
+
buffer << :foo
|
282
|
+
end
|
283
|
+
bar = spin do
|
284
|
+
sleep 0.2
|
285
|
+
ensure
|
286
|
+
buffer << :bar
|
287
|
+
end
|
288
|
+
|
289
|
+
s = spin { supervise }.detach
|
290
|
+
Fiber.current.attach_all_children_to(s)
|
291
|
+
|
292
|
+
s.terminate(true)
|
293
|
+
}
|
294
|
+
|
295
|
+
f.await
|
296
|
+
s.await
|
297
|
+
assert_equal [:foo, :bar], buffer
|
298
|
+
end
|
272
299
|
end
|
data/test/test_thread.rb
CHANGED
@@ -132,7 +132,7 @@ class ThreadTest < MiniTest::Test
|
|
132
132
|
Thread.backend.trace_proc = proc {|*r| records << r }
|
133
133
|
suspend
|
134
134
|
assert_equal [
|
135
|
-
[:
|
135
|
+
[:block, Fiber.current, ["#{__FILE__}:#{__LINE__ - 2}:in `test_that_suspend_returns_immediately_if_no_watchers'"] + caller]
|
136
136
|
], records
|
137
137
|
ensure
|
138
138
|
Thread.backend.trace_proc = nil
|
data/test/test_timer.rb
CHANGED
data/test/test_trace.rb
CHANGED
@@ -1,17 +1,29 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require_relative 'helper'
|
4
|
+
require 'polyphony/core/debug'
|
4
5
|
|
5
6
|
class TraceTest < MiniTest::Test
|
6
7
|
def test_tracing_enabled
|
7
8
|
events = []
|
8
|
-
|
9
|
+
|
10
|
+
Thread.backend.trace_proc = proc { |*e|
|
11
|
+
case e[0]
|
12
|
+
when :schedule
|
13
|
+
e = e[0..3]
|
14
|
+
when :block
|
15
|
+
e = e[0..1]
|
16
|
+
when :unblock
|
17
|
+
e = e[0..2]
|
18
|
+
end
|
19
|
+
events << e
|
20
|
+
}
|
9
21
|
snooze
|
10
22
|
|
11
23
|
assert_equal [
|
12
|
-
[:
|
13
|
-
[:
|
14
|
-
[:
|
24
|
+
[:schedule, Fiber.current, nil, false],
|
25
|
+
[:block, Fiber.current],
|
26
|
+
[:unblock, Fiber.current, nil]
|
15
27
|
], events
|
16
28
|
ensure
|
17
29
|
Thread.backend.trace_proc = nil
|
@@ -19,7 +31,17 @@ class TraceTest < MiniTest::Test
|
|
19
31
|
|
20
32
|
def test_2_fiber_trace
|
21
33
|
events = []
|
22
|
-
Thread.backend.trace_proc = proc { |*e|
|
34
|
+
Thread.backend.trace_proc = proc { |*e|
|
35
|
+
case e[0]
|
36
|
+
when :schedule
|
37
|
+
e = e[0..3]
|
38
|
+
when :spin, :block
|
39
|
+
e = e[0..1]
|
40
|
+
when :unblock
|
41
|
+
e = e[0..2]
|
42
|
+
end
|
43
|
+
events << e
|
44
|
+
}
|
23
45
|
|
24
46
|
f = spin { sleep 0; :byebye }
|
25
47
|
l0 = __LINE__ + 1
|
@@ -28,28 +50,84 @@ class TraceTest < MiniTest::Test
|
|
28
50
|
|
29
51
|
Thread.backend.trace_proc = nil
|
30
52
|
|
31
|
-
# remove caller info for :fiber_switchpoint events
|
32
|
-
events.each {|e| e.pop if e[0] == :fiber_switchpoint }
|
33
|
-
|
34
53
|
assert_equal [
|
35
|
-
[:
|
36
|
-
[:
|
37
|
-
[:
|
38
|
-
[:
|
39
|
-
[:
|
40
|
-
[:
|
41
|
-
[:
|
42
|
-
[:
|
43
|
-
[:
|
44
|
-
[:
|
45
|
-
[:
|
46
|
-
[:
|
47
|
-
[:
|
48
|
-
[:
|
49
|
-
[:
|
50
|
-
[:
|
54
|
+
[:spin, f],
|
55
|
+
[:schedule, f, nil, false],
|
56
|
+
[:block, Fiber.current],
|
57
|
+
[:unblock, f, nil],
|
58
|
+
[:block, f],
|
59
|
+
[:enter_poll, f],
|
60
|
+
[:schedule, f, nil, false],
|
61
|
+
[:leave_poll, f],
|
62
|
+
[:unblock, f, nil],
|
63
|
+
[:terminate, f, :byebye],
|
64
|
+
[:block, f],
|
65
|
+
[:block, Fiber.current],
|
66
|
+
[:enter_poll, Fiber.current],
|
67
|
+
[:schedule, Fiber.current, nil, false],
|
68
|
+
[:leave_poll, Fiber.current],
|
69
|
+
[:unblock, Fiber.current, nil]
|
51
70
|
], events
|
52
71
|
ensure
|
53
72
|
Thread.backend.trace_proc = nil
|
54
73
|
end
|
74
|
+
|
75
|
+
def test_event_firehose
|
76
|
+
buffer = []
|
77
|
+
Polyphony::Trace.start_event_firehose { |e| buffer << e }
|
78
|
+
|
79
|
+
f1 = spin(:f1) do
|
80
|
+
receive
|
81
|
+
end
|
82
|
+
|
83
|
+
f1 << :foo
|
84
|
+
f1.await
|
85
|
+
|
86
|
+
Thread.backend.trace_proc = nil
|
87
|
+
|
88
|
+
buffer.each { |e| e.delete(:stamp); e.delete(:caller) }
|
89
|
+
|
90
|
+
main = Fiber.current
|
91
|
+
assert_equal(
|
92
|
+
[
|
93
|
+
{ event: :spin, fiber: f1, source_fiber: main },
|
94
|
+
{ event: :schedule, fiber: f1, value: nil, source_fiber: main },
|
95
|
+
{ event: :block, fiber: main },
|
96
|
+
{ event: :unblock, fiber: f1, value: nil },
|
97
|
+
{ event: :schedule, fiber: f1, value: nil, source_fiber: f1 },
|
98
|
+
{ event: :block, fiber: f1, },
|
99
|
+
{ event: :enter_poll },
|
100
|
+
{ event: :leave_poll },
|
101
|
+
{ event: :unblock, fiber: f1, value: nil },
|
102
|
+
{ event: :terminate, fiber: f1, value: :foo },
|
103
|
+
{ event: :schedule, fiber: main, value: nil, source_fiber: f1 },
|
104
|
+
{ event: :block, fiber: f1 },
|
105
|
+
{ event: :unblock, fiber: main, value: nil }
|
106
|
+
], buffer
|
107
|
+
)
|
108
|
+
ensure
|
109
|
+
Thread.backend.trace_proc = nil
|
110
|
+
end
|
111
|
+
|
112
|
+
def test_event_firehose_with_io
|
113
|
+
r, w = IO.pipe
|
114
|
+
Polyphony::Trace.start_event_firehose(w)
|
115
|
+
|
116
|
+
f1 = spin(:f1) do
|
117
|
+
receive
|
118
|
+
end
|
119
|
+
|
120
|
+
f1 << :foo
|
121
|
+
f1.await
|
122
|
+
|
123
|
+
Thread.backend.trace_proc = nil
|
124
|
+
w.close
|
125
|
+
|
126
|
+
log = r.read
|
127
|
+
assert_equal 13, log.lines.size
|
128
|
+
|
129
|
+
# TODO: make sure log is formatted correctly
|
130
|
+
ensure
|
131
|
+
Thread.backend.trace_proc = nil
|
132
|
+
end
|
55
133
|
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.79'
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sharon Rosner
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-02-
|
11
|
+
date: 2022-02-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake-compiler
|
@@ -136,7 +136,7 @@ dependencies:
|
|
136
136
|
- - "~>"
|
137
137
|
- !ruby/object:Gem::Version
|
138
138
|
version: 1.1.4
|
139
|
-
description:
|
139
|
+
description:
|
140
140
|
email: sharon@noteflakes.com
|
141
141
|
executables: []
|
142
142
|
extensions:
|
@@ -245,6 +245,8 @@ files:
|
|
245
245
|
- examples/core/thread_pool.rb
|
246
246
|
- examples/core/throttling.rb
|
247
247
|
- examples/core/timeout.rb
|
248
|
+
- examples/core/trap1.rb
|
249
|
+
- examples/core/trap2.rb
|
248
250
|
- examples/core/using-a-mutex.rb
|
249
251
|
- examples/core/worker-thread.rb
|
250
252
|
- examples/io/backticks.rb
|
@@ -346,6 +348,7 @@ files:
|
|
346
348
|
- ext/polyphony/runqueue_ring_buffer.h
|
347
349
|
- ext/polyphony/socket_extensions.c
|
348
350
|
- ext/polyphony/thread.c
|
351
|
+
- ext/test_eintr.c
|
349
352
|
- lib/polyphony.rb
|
350
353
|
- lib/polyphony/adapters/fs.rb
|
351
354
|
- lib/polyphony/adapters/irb.rb
|
@@ -412,7 +415,7 @@ metadata:
|
|
412
415
|
documentation_uri: https://digital-fabric.github.io/polyphony/
|
413
416
|
homepage_uri: https://digital-fabric.github.io/polyphony/
|
414
417
|
changelog_uri: https://github.com/digital-fabric/polyphony/blob/master/CHANGELOG.md
|
415
|
-
post_install_message:
|
418
|
+
post_install_message:
|
416
419
|
rdoc_options:
|
417
420
|
- "--title"
|
418
421
|
- polyphony
|
@@ -431,8 +434,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
431
434
|
- !ruby/object:Gem::Version
|
432
435
|
version: '0'
|
433
436
|
requirements: []
|
434
|
-
rubygems_version: 3.
|
435
|
-
signing_key:
|
437
|
+
rubygems_version: 3.3.3
|
438
|
+
signing_key:
|
436
439
|
specification_version: 4
|
437
440
|
summary: Fine grained concurrency for Ruby
|
438
441
|
test_files: []
|