polyphony 0.78 → 0.81

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.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +19 -0
  3. data/Gemfile.lock +2 -1
  4. data/examples/core/pingpong.rb +7 -4
  5. data/examples/core/zlib_stream.rb +15 -0
  6. data/ext/polyphony/backend_common.c +16 -8
  7. data/ext/polyphony/backend_common.h +9 -3
  8. data/ext/polyphony/backend_io_uring.c +85 -31
  9. data/ext/polyphony/backend_libev.c +33 -17
  10. data/ext/polyphony/fiber.c +27 -27
  11. data/ext/polyphony/polyphony.c +9 -8
  12. data/ext/polyphony/polyphony.h +21 -7
  13. data/ext/polyphony/thread.c +6 -2
  14. data/lib/polyphony/adapters/fs.rb +4 -0
  15. data/lib/polyphony/adapters/process.rb +14 -1
  16. data/lib/polyphony/adapters/redis.rb +28 -0
  17. data/lib/polyphony/adapters/sequel.rb +19 -1
  18. data/lib/polyphony/core/debug.rb +201 -0
  19. data/lib/polyphony/core/exceptions.rb +21 -6
  20. data/lib/polyphony/core/global_api.rb +228 -73
  21. data/lib/polyphony/core/resource_pool.rb +65 -20
  22. data/lib/polyphony/core/sync.rb +57 -12
  23. data/lib/polyphony/core/thread_pool.rb +42 -5
  24. data/lib/polyphony/core/throttler.rb +21 -5
  25. data/lib/polyphony/core/timer.rb +125 -1
  26. data/lib/polyphony/extensions/exception.rb +36 -6
  27. data/lib/polyphony/extensions/fiber.rb +244 -61
  28. data/lib/polyphony/extensions/io.rb +4 -2
  29. data/lib/polyphony/extensions/kernel.rb +9 -4
  30. data/lib/polyphony/extensions/object.rb +8 -0
  31. data/lib/polyphony/extensions/openssl.rb +3 -1
  32. data/lib/polyphony/extensions/socket.rb +458 -39
  33. data/lib/polyphony/extensions/thread.rb +108 -43
  34. data/lib/polyphony/extensions/timeout.rb +12 -1
  35. data/lib/polyphony/extensions.rb +1 -0
  36. data/lib/polyphony/net.rb +66 -7
  37. data/lib/polyphony/version.rb +1 -1
  38. data/lib/polyphony.rb +0 -2
  39. data/test/test_backend.rb +6 -2
  40. data/test/test_global_api.rb +0 -23
  41. data/test/test_io.rb +7 -7
  42. data/test/test_resource_pool.rb +1 -1
  43. data/test/test_signal.rb +15 -15
  44. data/test/test_thread.rb +1 -1
  45. data/test/test_throttler.rb +0 -6
  46. data/test/test_trace.rb +189 -24
  47. metadata +9 -8
  48. data/lib/polyphony/core/channel.rb +0 -15
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
- Thread.backend.trace_proc = proc { |*e| events << e }
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
- [:fiber_schedule, Fiber.current, nil, false],
13
- [:fiber_switchpoint, Fiber.current, ["#{__FILE__}:#{__LINE__ - 4}:in `test_tracing_enabled'"] + caller],
14
- [:fiber_run, Fiber.current, nil]
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| events << 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,171 @@ 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
- [:fiber_create, f],
36
- [:fiber_schedule, f, nil, false],
37
- [:fiber_switchpoint, Fiber.current],
38
- [:fiber_run, f, nil],
39
- [:fiber_switchpoint, f],
40
- [:fiber_event_poll_enter, f],
41
- [:fiber_schedule, f, nil, false],
42
- [:fiber_event_poll_leave, f],
43
- [:fiber_run, f, nil],
44
- [:fiber_terminate, f, :byebye],
45
- [:fiber_switchpoint, f],
46
- [:fiber_switchpoint, Fiber.current],
47
- [:fiber_event_poll_enter, Fiber.current],
48
- [:fiber_schedule, Fiber.current, nil, false],
49
- [:fiber_event_poll_leave, Fiber.current],
50
- [:fiber_run, Fiber.current, nil]
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
133
+
134
+ def test_event_firehose_with_threaded_receiver
135
+ buffer = []
136
+ this = Fiber.current
137
+ receiver = Thread.new {
138
+ this << :ok
139
+ loop {
140
+ e = receive
141
+ break if e == :stop
142
+ buffer << e
143
+ }
144
+ }
145
+ receive
146
+
147
+ Polyphony::Trace.start_event_firehose { |e| receiver << e }
148
+
149
+ f1 = spin(:f1) do
150
+ receive
151
+ end
152
+
153
+ f1 << :foo
154
+ f1.await
155
+
156
+ Thread.backend.trace_proc = nil
157
+ receiver << :stop
158
+ receiver.await
159
+
160
+ buffer.each { |e| e.delete(:stamp); e.delete(:caller) }
161
+
162
+ main = Fiber.current
163
+ assert_equal(
164
+ [
165
+ { event: :spin, fiber: f1, source_fiber: main },
166
+ { event: :schedule, fiber: f1, value: nil, source_fiber: main },
167
+ { event: :block, fiber: main },
168
+ { event: :unblock, fiber: f1, value: nil },
169
+ { event: :schedule, fiber: f1, value: nil, source_fiber: f1 },
170
+ { event: :block, fiber: f1, },
171
+ { event: :enter_poll },
172
+ { event: :leave_poll },
173
+ { event: :unblock, fiber: f1, value: nil },
174
+ { event: :terminate, fiber: f1, value: :foo },
175
+ { event: :schedule, fiber: main, value: nil, source_fiber: f1 },
176
+ { event: :block, fiber: f1 },
177
+ { event: :unblock, fiber: main, value: nil }
178
+ ], buffer
179
+ )
180
+ ensure
181
+ Thread.backend.trace_proc = nil
182
+ end
183
+
184
+ # def test_event_firehose_with_reentrancy
185
+ # buffer = []
186
+ # Polyphony::Trace.start_event_firehose { |e| buffer << e }
187
+
188
+ # f1 = spin(:f1) do
189
+ # receive
190
+ # end
191
+
192
+ # f1 << :foo
193
+ # f1.await
194
+
195
+ # Thread.backend.trace_proc = nil
196
+ # buffer.each { |e| e.delete(:stamp); e.delete(:caller) }
197
+
198
+ # main = Fiber.current
199
+ # assert_equal(
200
+ # [
201
+ # { event: :spin, fiber: f1, source_fiber: main },
202
+ # { event: :schedule, fiber: f1, value: nil, source_fiber: main },
203
+ # { event: :block, fiber: main },
204
+ # { event: :unblock, fiber: f1, value: nil },
205
+ # { event: :schedule, fiber: f1, value: nil, source_fiber: f1 },
206
+ # { event: :block, fiber: f1, },
207
+ # { event: :enter_poll },
208
+ # { event: :leave_poll },
209
+ # { event: :unblock, fiber: f1, value: nil },
210
+ # { event: :terminate, fiber: f1, value: :foo },
211
+ # { event: :schedule, fiber: main, value: nil, source_fiber: f1 },
212
+ # { event: :block, fiber: f1 },
213
+ # { event: :unblock, fiber: main, value: nil }
214
+ # ], buffer
215
+ # )
216
+ # ensure
217
+ # Thread.backend.trace_proc = nil
218
+ # end
219
+
55
220
  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.78'
4
+ version: '0.81'
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-16 00:00:00.000000000 Z
11
+ date: 2022-03-03 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:
@@ -249,6 +249,7 @@ files:
249
249
  - examples/core/trap2.rb
250
250
  - examples/core/using-a-mutex.rb
251
251
  - examples/core/worker-thread.rb
252
+ - examples/core/zlib_stream.rb
252
253
  - examples/io/backticks.rb
253
254
  - examples/io/echo_client.rb
254
255
  - examples/io/echo_client_from_stdin.rb
@@ -358,7 +359,6 @@ files:
358
359
  - lib/polyphony/adapters/readline.rb
359
360
  - lib/polyphony/adapters/redis.rb
360
361
  - lib/polyphony/adapters/sequel.rb
361
- - lib/polyphony/core/channel.rb
362
362
  - lib/polyphony/core/debug.rb
363
363
  - lib/polyphony/core/exceptions.rb
364
364
  - lib/polyphony/core/global_api.rb
@@ -373,6 +373,7 @@ files:
373
373
  - lib/polyphony/extensions/fiber.rb
374
374
  - lib/polyphony/extensions/io.rb
375
375
  - lib/polyphony/extensions/kernel.rb
376
+ - lib/polyphony/extensions/object.rb
376
377
  - lib/polyphony/extensions/openssl.rb
377
378
  - lib/polyphony/extensions/process.rb
378
379
  - lib/polyphony/extensions/socket.rb
@@ -415,7 +416,7 @@ metadata:
415
416
  documentation_uri: https://digital-fabric.github.io/polyphony/
416
417
  homepage_uri: https://digital-fabric.github.io/polyphony/
417
418
  changelog_uri: https://github.com/digital-fabric/polyphony/blob/master/CHANGELOG.md
418
- post_install_message:
419
+ post_install_message:
419
420
  rdoc_options:
420
421
  - "--title"
421
422
  - polyphony
@@ -434,8 +435,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
434
435
  - !ruby/object:Gem::Version
435
436
  version: '0'
436
437
  requirements: []
437
- rubygems_version: 3.3.3
438
- signing_key:
438
+ rubygems_version: 3.1.6
439
+ signing_key:
439
440
  specification_version: 4
440
441
  summary: Fine grained concurrency for Ruby
441
442
  test_files: []
@@ -1,15 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative './exceptions'
4
-
5
- module Polyphony
6
- # Implements a unidirectional communication channel along the lines of Go
7
- # (buffered) channels.
8
- class Channel < Polyphony::Queue
9
- alias_method :receive, :shift
10
-
11
- def close
12
- flush_waiters(Polyphony::MoveOn.new)
13
- end
14
- end
15
- end