polyphony 0.46.1 → 0.47.0
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 +8 -0
- data/Gemfile.lock +1 -1
- data/TODO.md +0 -14
- data/examples/core/enumerable.rb +64 -0
- data/examples/performance/fiber_resume.rb +43 -0
- data/examples/performance/thread-vs-fiber/compare.rb +59 -0
- data/examples/performance/thread-vs-fiber/em_server.rb +33 -0
- data/examples/performance/thread-vs-fiber/polyphony_server.rb +4 -3
- data/examples/performance/thread-vs-fiber/threaded_server.rb +22 -15
- data/examples/performance/thread_switch.rb +44 -0
- data/ext/polyphony/backend_common.h +9 -0
- data/ext/polyphony/backend_io_uring.c +81 -5
- data/ext/polyphony/backend_io_uring_context.c +1 -0
- data/ext/polyphony/backend_io_uring_context.h +1 -0
- data/ext/polyphony/backend_libev.c +67 -0
- data/ext/polyphony/fiber.c +10 -1
- data/ext/polyphony/polyphony.c +3 -0
- data/ext/polyphony/polyphony.h +3 -6
- data/ext/polyphony/queue.c +99 -34
- data/lib/polyphony/core/global_api.rb +40 -18
- data/lib/polyphony/extensions/fiber.rb +6 -2
- data/lib/polyphony/version.rb +1 -1
- data/test/test_backend.rb +48 -0
- data/test/test_fiber.rb +33 -4
- data/test/test_global_api.rb +61 -0
- data/test/test_queue.rb +117 -0
- metadata +7 -2
@@ -328,14 +328,18 @@ class ::Fiber
|
|
328
328
|
extend Polyphony::FiberControlClassMethods
|
329
329
|
|
330
330
|
attr_accessor :tag, :thread, :parent
|
331
|
-
attr_reader :result
|
331
|
+
attr_reader :result
|
332
332
|
|
333
333
|
def running?
|
334
334
|
@running
|
335
335
|
end
|
336
336
|
|
337
337
|
def inspect
|
338
|
-
|
338
|
+
if @tag
|
339
|
+
"#<Fiber #{tag}:#{object_id} #{location} (#{state})>"
|
340
|
+
else
|
341
|
+
"#<Fiber:#{object_id} #{location} (#{state})>"
|
342
|
+
end
|
339
343
|
end
|
340
344
|
alias_method :to_s, :inspect
|
341
345
|
|
data/lib/polyphony/version.rb
CHANGED
data/test/test_backend.rb
CHANGED
@@ -136,4 +136,52 @@ class BackendTest < MiniTest::Test
|
|
136
136
|
f.await # TODO: check why this test sometimes segfaults if we don't a<wait fiber
|
137
137
|
assert_in_range 4..6, i
|
138
138
|
end
|
139
|
+
|
140
|
+
class MyTimeoutException < Exception
|
141
|
+
end
|
142
|
+
|
143
|
+
def test_timeout
|
144
|
+
buffer = []
|
145
|
+
assert_raises(Polyphony::TimeoutException) do
|
146
|
+
@backend.timeout(0.01, Polyphony::TimeoutException) do
|
147
|
+
buffer << 1
|
148
|
+
sleep 0.02
|
149
|
+
buffer << 2
|
150
|
+
end
|
151
|
+
end
|
152
|
+
assert_equal [1], buffer
|
153
|
+
|
154
|
+
buffer = []
|
155
|
+
assert_raises(MyTimeoutException) do
|
156
|
+
@backend.timeout(0.01, MyTimeoutException) do
|
157
|
+
buffer << 1
|
158
|
+
sleep 1
|
159
|
+
buffer << 2
|
160
|
+
end
|
161
|
+
end
|
162
|
+
assert_equal [1], buffer
|
163
|
+
|
164
|
+
buffer = []
|
165
|
+
result = @backend.timeout(0.01, nil, 42) do
|
166
|
+
buffer << 1
|
167
|
+
sleep 1
|
168
|
+
buffer << 2
|
169
|
+
end
|
170
|
+
assert_equal 42, result
|
171
|
+
assert_equal [1], buffer
|
172
|
+
end
|
173
|
+
|
174
|
+
def test_nested_timeout
|
175
|
+
buffer = []
|
176
|
+
assert_raises(MyTimeoutException) do
|
177
|
+
@backend.timeout(0.01, MyTimeoutException) do
|
178
|
+
@backend.timeout(0.02, nil) do
|
179
|
+
buffer << 1
|
180
|
+
sleep 1
|
181
|
+
buffer << 2
|
182
|
+
end
|
183
|
+
end
|
184
|
+
end
|
185
|
+
assert_equal [1], buffer
|
186
|
+
end
|
139
187
|
end
|
data/test/test_fiber.rb
CHANGED
@@ -565,14 +565,14 @@ class FiberTest < MiniTest::Test
|
|
565
565
|
end
|
566
566
|
|
567
567
|
def test_inspect
|
568
|
-
expected = format('#<Fiber:%s (root) (running)>', Fiber.current.object_id)
|
568
|
+
expected = format('#<Fiber main:%s (root) (running)>', Fiber.current.object_id)
|
569
569
|
assert_equal expected, Fiber.current.inspect
|
570
570
|
|
571
571
|
spin_line_no = __LINE__ + 1
|
572
|
-
f = spin { :foo }
|
572
|
+
f = spin(:baz) { :foo }
|
573
573
|
|
574
574
|
expected = format(
|
575
|
-
'#<Fiber:%s %s:%d:in `test_inspect\' (runnable)>',
|
575
|
+
'#<Fiber baz:%s %s:%d:in `test_inspect\' (runnable)>',
|
576
576
|
f.object_id,
|
577
577
|
__FILE__,
|
578
578
|
spin_line_no
|
@@ -581,7 +581,7 @@ class FiberTest < MiniTest::Test
|
|
581
581
|
|
582
582
|
f.await
|
583
583
|
expected = format(
|
584
|
-
'#<Fiber:%s %s:%d:in `test_inspect\' (dead)>',
|
584
|
+
'#<Fiber baz:%s %s:%d:in `test_inspect\' (dead)>',
|
585
585
|
f.object_id,
|
586
586
|
__FILE__,
|
587
587
|
spin_line_no
|
@@ -738,6 +738,35 @@ class MailboxTest < MiniTest::Test
|
|
738
738
|
f&.stop
|
739
739
|
end
|
740
740
|
|
741
|
+
def test_capped_fiber_mailbox
|
742
|
+
buffer = []
|
743
|
+
a = spin_loop do
|
744
|
+
3.times { snooze }
|
745
|
+
buffer << [:receive, receive]
|
746
|
+
end
|
747
|
+
a.mailbox.cap(1)
|
748
|
+
|
749
|
+
b = spin do
|
750
|
+
(1..3).each do |i|
|
751
|
+
a << i
|
752
|
+
buffer << [:send, i]
|
753
|
+
end
|
754
|
+
end
|
755
|
+
|
756
|
+
(1..10).each do |i|
|
757
|
+
snooze
|
758
|
+
buffer << [:snooze, i]
|
759
|
+
end
|
760
|
+
|
761
|
+
b.join
|
762
|
+
|
763
|
+
assert_equal [
|
764
|
+
[:snooze, 1], [:send, 1], [:snooze, 2], [:snooze, 3], [:snooze, 4],
|
765
|
+
[:receive, 1], [:snooze, 5], [:send, 2], [:snooze, 6], [:snooze, 7],
|
766
|
+
[:snooze, 8], [:receive, 2], [:snooze, 9], [:send, 3], [:snooze, 10]
|
767
|
+
], buffer
|
768
|
+
end
|
769
|
+
|
741
770
|
def test_that_multiple_messages_sent_at_once_arrive_in_order
|
742
771
|
msgs = []
|
743
772
|
f = spin { loop { msgs << receive } }
|
data/test/test_global_api.rb
CHANGED
@@ -150,6 +150,28 @@ class MoveOnAfterTest < MiniTest::Test
|
|
150
150
|
assert t1 - t0 < 0.1
|
151
151
|
assert_equal 'foo', v
|
152
152
|
end
|
153
|
+
|
154
|
+
def test_nested_move_on_after
|
155
|
+
t0 = Time.now
|
156
|
+
o = move_on_after(0.01, with_value: 1) do
|
157
|
+
move_on_after(0.02, with_value: 2) do
|
158
|
+
sleep 1
|
159
|
+
end
|
160
|
+
end
|
161
|
+
t1 = Time.now
|
162
|
+
assert_equal 1, o
|
163
|
+
assert_in_range 0.008..0.013, t1 - t0
|
164
|
+
|
165
|
+
t0 = Time.now
|
166
|
+
o = move_on_after(0.02, with_value: 1) do
|
167
|
+
move_on_after(0.01, with_value: 2) do
|
168
|
+
sleep 1
|
169
|
+
end
|
170
|
+
end
|
171
|
+
t1 = Time.now
|
172
|
+
assert_equal 2, o
|
173
|
+
assert_in_range 0.008..0.013, t1 - t0
|
174
|
+
end
|
153
175
|
end
|
154
176
|
|
155
177
|
class CancelAfterTest < MiniTest::Test
|
@@ -277,6 +299,45 @@ class SpinLoopTest < MiniTest::Test
|
|
277
299
|
end
|
278
300
|
end
|
279
301
|
|
302
|
+
class SpinScopeTest < MiniTest::Test
|
303
|
+
def test_spin_scope
|
304
|
+
queue = Queue.new
|
305
|
+
buffer = {}
|
306
|
+
spin do
|
307
|
+
queue << 1
|
308
|
+
snooze
|
309
|
+
queue << 2
|
310
|
+
end
|
311
|
+
f = nil
|
312
|
+
result = spin_scope do
|
313
|
+
f = Fiber.current
|
314
|
+
spin { buffer[:a] = queue.shift }
|
315
|
+
spin { buffer[:b] = queue.shift }
|
316
|
+
:foo
|
317
|
+
end
|
318
|
+
assert_equal :foo, result
|
319
|
+
assert_kind_of Fiber, f
|
320
|
+
assert_equal :dead, f.state
|
321
|
+
assert_equal ({a: 1, b: 2}), buffer
|
322
|
+
end
|
323
|
+
|
324
|
+
def test_spin_scope_with_exception
|
325
|
+
queue = Queue.new
|
326
|
+
buffer = []
|
327
|
+
spin do
|
328
|
+
spin_scope do
|
329
|
+
spin { buffer << queue.shift }
|
330
|
+
spin { raise 'foobar' }
|
331
|
+
end
|
332
|
+
rescue => e
|
333
|
+
buffer << e.message
|
334
|
+
end
|
335
|
+
6.times { snooze }
|
336
|
+
assert_equal 0, Fiber.current.children.size
|
337
|
+
assert_equal ['foobar'], buffer
|
338
|
+
end
|
339
|
+
end
|
340
|
+
|
280
341
|
class ThrottledLoopTest < MiniTest::Test
|
281
342
|
def test_throttled_loop
|
282
343
|
buffer = []
|
data/test/test_queue.rb
CHANGED
@@ -130,3 +130,120 @@ class QueueTest < MiniTest::Test
|
|
130
130
|
assert_equal 0, @queue.size
|
131
131
|
end
|
132
132
|
end
|
133
|
+
|
134
|
+
class CappedQueueTest < MiniTest::Test
|
135
|
+
def setup
|
136
|
+
super
|
137
|
+
@queue = Polyphony::Queue.new
|
138
|
+
@queue.cap(3)
|
139
|
+
end
|
140
|
+
|
141
|
+
def test_capped?
|
142
|
+
q = Polyphony::Queue.new
|
143
|
+
assert_nil q.capped?
|
144
|
+
|
145
|
+
q.cap(3)
|
146
|
+
assert_equal 3, q.capped?
|
147
|
+
end
|
148
|
+
|
149
|
+
def test_initalize_with_cap
|
150
|
+
q = Polyphony::Queue.new(42)
|
151
|
+
assert_equal 42, q.capped?
|
152
|
+
end
|
153
|
+
|
154
|
+
def test_capped_push
|
155
|
+
buffer = []
|
156
|
+
a = spin do
|
157
|
+
(1..5).each do |i|
|
158
|
+
@queue.push(i)
|
159
|
+
buffer << :"p#{i}"
|
160
|
+
end
|
161
|
+
@queue.push :stop
|
162
|
+
end
|
163
|
+
|
164
|
+
snooze
|
165
|
+
|
166
|
+
b = spin_loop do
|
167
|
+
i = @queue.shift
|
168
|
+
raise Polyphony::Terminate if i == :stop
|
169
|
+
buffer << :"s#{i}"
|
170
|
+
end
|
171
|
+
|
172
|
+
Fiber.join(a, b)
|
173
|
+
assert_equal [:p1, :p2, :s1, :p3, :s2, :p4, :s3, :p5, :s4, :s5], buffer
|
174
|
+
end
|
175
|
+
|
176
|
+
def test_capped_multi_push
|
177
|
+
buffer = []
|
178
|
+
a = spin(:a) do
|
179
|
+
(1..3).each do |i|
|
180
|
+
@queue.push(i)
|
181
|
+
buffer << :"p#{i}"
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
buffer = []
|
186
|
+
b = spin(:b) do
|
187
|
+
(4..6).each do |i|
|
188
|
+
@queue.push(i)
|
189
|
+
buffer << :"p#{i}"
|
190
|
+
end
|
191
|
+
@queue.push :stop
|
192
|
+
end
|
193
|
+
|
194
|
+
c = spin_loop do
|
195
|
+
i = @queue.shift
|
196
|
+
raise Polyphony::Terminate if i == :stop
|
197
|
+
buffer << :"s#{i}"
|
198
|
+
snooze
|
199
|
+
end
|
200
|
+
|
201
|
+
Fiber.join(a, b, c)
|
202
|
+
assert_equal [:p1, :p4, :s1, :p5, :p2, :s4, :p3, :s5, :p6, :s2, :s3, :s6], buffer
|
203
|
+
end
|
204
|
+
|
205
|
+
def test_capped_clear
|
206
|
+
buffer = []
|
207
|
+
a = spin(:a) do
|
208
|
+
(1..5).each do |i|
|
209
|
+
@queue.push(i)
|
210
|
+
buffer << i
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
214
|
+
snooze while buffer.size < 3
|
215
|
+
@queue.clear
|
216
|
+
buffer << :clear
|
217
|
+
|
218
|
+
a.join
|
219
|
+
assert_equal [1, 2, 3, :clear, 4, 5], buffer
|
220
|
+
end
|
221
|
+
|
222
|
+
def test_capped_delete
|
223
|
+
buffer = []
|
224
|
+
a = spin(:a) do
|
225
|
+
(1..5).each do |i|
|
226
|
+
@queue.push(i)
|
227
|
+
buffer << i
|
228
|
+
end
|
229
|
+
end
|
230
|
+
|
231
|
+
i = 0
|
232
|
+
spin_loop do
|
233
|
+
i += 1
|
234
|
+
snooze
|
235
|
+
end
|
236
|
+
|
237
|
+
5.times { snooze }
|
238
|
+
assert_equal 5, i
|
239
|
+
@queue.delete 1
|
240
|
+
buffer << :"d#{i}"
|
241
|
+
3.times { snooze }
|
242
|
+
assert_equal 8, i
|
243
|
+
@queue.delete 2
|
244
|
+
buffer << :"d#{i}"
|
245
|
+
|
246
|
+
a.join
|
247
|
+
assert_equal [1, 2, 3, :d5, 4, :d8, 5], buffer
|
248
|
+
end
|
249
|
+
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.47.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sharon Rosner
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-11-
|
11
|
+
date: 2020-11-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake-compiler
|
@@ -348,6 +348,7 @@ files:
|
|
348
348
|
- examples/core/await.rb
|
349
349
|
- examples/core/channels.rb
|
350
350
|
- examples/core/deferring-an-operation.rb
|
351
|
+
- examples/core/enumerable.rb
|
351
352
|
- examples/core/erlang-style-genserver.rb
|
352
353
|
- examples/core/forking.rb
|
353
354
|
- examples/core/handling-signals.rb
|
@@ -386,6 +387,7 @@ files:
|
|
386
387
|
- examples/io/tcpsocket.rb
|
387
388
|
- examples/io/tunnel.rb
|
388
389
|
- examples/io/zip.rb
|
390
|
+
- examples/performance/fiber_resume.rb
|
389
391
|
- examples/performance/fiber_transfer.rb
|
390
392
|
- examples/performance/fs_read.rb
|
391
393
|
- examples/performance/mem-usage.rb
|
@@ -394,6 +396,8 @@ files:
|
|
394
396
|
- examples/performance/snooze.rb
|
395
397
|
- examples/performance/snooze_raw.rb
|
396
398
|
- examples/performance/switch.rb
|
399
|
+
- examples/performance/thread-vs-fiber/compare.rb
|
400
|
+
- examples/performance/thread-vs-fiber/em_server.rb
|
397
401
|
- examples/performance/thread-vs-fiber/httparty_multi.rb
|
398
402
|
- examples/performance/thread-vs-fiber/httparty_threaded.rb
|
399
403
|
- examples/performance/thread-vs-fiber/polyphony_mt_server.rb
|
@@ -401,6 +405,7 @@ files:
|
|
401
405
|
- examples/performance/thread-vs-fiber/polyphony_server_read_loop.rb
|
402
406
|
- examples/performance/thread-vs-fiber/threaded_server.rb
|
403
407
|
- examples/performance/thread_pool_perf.rb
|
408
|
+
- examples/performance/thread_switch.rb
|
404
409
|
- ext/libev/Changes
|
405
410
|
- ext/libev/LICENSE
|
406
411
|
- ext/libev/README
|