polyphony 0.33 → 0.34
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 +93 -68
- data/bin/polyphony-debug +87 -0
- data/docs/_includes/nav.html +5 -1
- data/docs/_sass/overrides.scss +4 -1
- data/docs/api-reference.md +11 -0
- data/docs/api-reference/exception.md +27 -0
- data/docs/api-reference/fiber.md +407 -0
- data/docs/api-reference/io.md +36 -0
- data/docs/api-reference/object.md +99 -0
- data/docs/api-reference/polyphony-baseexception.md +33 -0
- data/docs/api-reference/polyphony-cancel.md +26 -0
- data/docs/api-reference/polyphony-moveon.md +24 -0
- data/docs/api-reference/polyphony-net.md +20 -0
- data/docs/api-reference/polyphony-process.md +28 -0
- data/docs/api-reference/polyphony-resourcepool.md +59 -0
- data/docs/api-reference/polyphony-restart.md +18 -0
- data/docs/api-reference/polyphony-terminate.md +18 -0
- data/docs/api-reference/polyphony-threadpool.md +67 -0
- data/docs/api-reference/polyphony-throttler.md +77 -0
- data/docs/api-reference/polyphony.md +36 -0
- data/docs/api-reference/thread.md +88 -0
- data/docs/getting-started/tutorial.md +59 -156
- data/docs/index.md +2 -0
- data/examples/core/forever_sleep.rb +19 -0
- data/examples/core/xx-caller.rb +12 -0
- data/examples/core/xx-exception-backtrace.rb +40 -0
- data/examples/core/xx-fork-spin.rb +42 -0
- data/examples/core/xx-spin-fork.rb +49 -0
- data/examples/core/xx-supervise-process.rb +30 -0
- data/ext/gyro/gyro.h +1 -0
- data/ext/gyro/selector.c +8 -0
- data/ext/gyro/thread.c +8 -2
- data/lib/polyphony.rb +64 -17
- data/lib/polyphony/adapters/process.rb +29 -0
- data/lib/polyphony/adapters/trace.rb +6 -4
- data/lib/polyphony/core/exceptions.rb +5 -0
- data/lib/polyphony/core/global_api.rb +15 -0
- data/lib/polyphony/extensions/fiber.rb +89 -59
- data/lib/polyphony/version.rb +1 -1
- data/test/test_fiber.rb +23 -75
- data/test/test_global_api.rb +39 -0
- data/test/test_kernel.rb +5 -7
- data/test/test_process_supervision.rb +46 -0
- data/test/test_signal.rb +2 -3
- data/test/test_supervise.rb +103 -0
- metadata +29 -2
data/lib/polyphony/version.rb
CHANGED
data/test/test_fiber.rb
CHANGED
@@ -659,20 +659,41 @@ class FiberTest < MiniTest::Test
|
|
659
659
|
i, o = IO.pipe
|
660
660
|
pid = Polyphony.fork do
|
661
661
|
i.close
|
662
|
-
|
662
|
+
spin do
|
663
663
|
sleep 100
|
664
664
|
rescue Exception => e
|
665
665
|
o << e.class.to_s
|
666
666
|
o.close
|
667
|
+
raise e
|
667
668
|
end
|
668
|
-
|
669
|
+
suspend
|
669
670
|
end
|
670
671
|
o.close
|
672
|
+
spin do
|
673
|
+
sleep 0.2
|
674
|
+
Process.kill('TERM', pid)
|
675
|
+
end
|
671
676
|
Gyro::Child.new(pid).await
|
672
677
|
klass = i.read
|
673
678
|
i.close
|
674
679
|
assert_equal 'Polyphony::Terminate', klass
|
675
680
|
end
|
681
|
+
|
682
|
+
def test_setup_raw
|
683
|
+
buffer = []
|
684
|
+
f = Fiber.new { buffer << receive }
|
685
|
+
|
686
|
+
assert_raises(NoMethodError) { f << 'foo' }
|
687
|
+
snooze
|
688
|
+
f.setup_raw
|
689
|
+
assert_equal Thread.current, f.thread
|
690
|
+
assert_nil f.parent
|
691
|
+
|
692
|
+
f.schedule
|
693
|
+
f << 'bar'
|
694
|
+
snooze
|
695
|
+
assert_equal ['bar'], buffer
|
696
|
+
end
|
676
697
|
end
|
677
698
|
|
678
699
|
class MailboxTest < MiniTest::Test
|
@@ -956,76 +977,3 @@ class RestartTest < MiniTest::Test
|
|
956
977
|
assert_equal [f, 'foo', 'bar', :done, f2, 'baz', 42, :done], buffer
|
957
978
|
end
|
958
979
|
end
|
959
|
-
|
960
|
-
class SuperviseTest < MiniTest::Test
|
961
|
-
def test_supervise
|
962
|
-
p = spin { supervise }
|
963
|
-
snooze
|
964
|
-
f1 = p.spin { receive }
|
965
|
-
f2 = p.spin { receive }
|
966
|
-
|
967
|
-
snooze
|
968
|
-
assert_equal p.state, :waiting
|
969
|
-
f1 << 'foo'
|
970
|
-
f1.await
|
971
|
-
snooze
|
972
|
-
|
973
|
-
assert_equal :waiting, p.state
|
974
|
-
assert_equal :waiting, f2.state
|
975
|
-
|
976
|
-
f2 << 'bar'
|
977
|
-
f2.await
|
978
|
-
snooze
|
979
|
-
|
980
|
-
assert_equal :waiting, p.state
|
981
|
-
end
|
982
|
-
|
983
|
-
def test_supervise_with_restart
|
984
|
-
parent = spin { supervise(on_error: :restart) }
|
985
|
-
snooze
|
986
|
-
|
987
|
-
buffer = []
|
988
|
-
f1 = parent.spin do
|
989
|
-
buffer << 'f1'
|
990
|
-
buffer << receive
|
991
|
-
end
|
992
|
-
|
993
|
-
snooze
|
994
|
-
assert_equal ['f1'], buffer
|
995
|
-
|
996
|
-
f1.raise 'foo'
|
997
|
-
|
998
|
-
3.times { snooze }
|
999
|
-
|
1000
|
-
assert_equal ['f1', 'f1'], buffer
|
1001
|
-
assert_equal :dead, f1.state
|
1002
|
-
|
1003
|
-
# f1 should have been restarted by supervisor
|
1004
|
-
f1 = parent.children.first
|
1005
|
-
assert_kind_of Fiber, f1
|
1006
|
-
f1 << 'foo'
|
1007
|
-
|
1008
|
-
f1.await
|
1009
|
-
3.times { snooze }
|
1010
|
-
|
1011
|
-
assert_equal ['f1', 'f1', 'foo'], buffer
|
1012
|
-
end
|
1013
|
-
|
1014
|
-
def test_supervise_with_block
|
1015
|
-
failed = []
|
1016
|
-
p = spin do
|
1017
|
-
supervise(on_error: :restart) { |f, e| failed << [f, e] }
|
1018
|
-
end
|
1019
|
-
snooze
|
1020
|
-
f1 = p.spin { receive }
|
1021
|
-
snooze
|
1022
|
-
|
1023
|
-
f1.raise 'foo'
|
1024
|
-
3.times { snooze }
|
1025
|
-
|
1026
|
-
assert_equal 1, failed.size
|
1027
|
-
assert_equal f1, failed.first[0]
|
1028
|
-
assert_kind_of RuntimeError, failed.first[1]
|
1029
|
-
assert_equal 'foo', failed.first[1].message
|
1030
|
-
end
|
1031
|
-
end
|
data/test/test_global_api.rb
CHANGED
@@ -121,8 +121,47 @@ class MoveOnAfterTest < MiniTest::Test
|
|
121
121
|
assert t1 - t0 < 0.02
|
122
122
|
assert_equal :bar, v
|
123
123
|
end
|
124
|
+
|
125
|
+
def test_move_on_after_without_block
|
126
|
+
t0 = Time.now
|
127
|
+
f = move_on_after(0.01, with_value: 'foo')
|
128
|
+
assert_kind_of Fiber, f
|
129
|
+
assert_equal Fiber.current, f.parent
|
130
|
+
v = sleep 1
|
131
|
+
t1 = Time.now
|
132
|
+
assert t1 - t0 < 0.02
|
133
|
+
assert_equal 'foo', v
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
class CancelAfterTest < MiniTest::Test
|
138
|
+
def test_cancel_after
|
139
|
+
t0 = Time.now
|
140
|
+
|
141
|
+
assert_raises Polyphony::Cancel do
|
142
|
+
cancel_after(0.01) do
|
143
|
+
sleep 1
|
144
|
+
:foo
|
145
|
+
end
|
146
|
+
end
|
147
|
+
t1 = Time.now
|
148
|
+
assert t1 - t0 < 0.02
|
149
|
+
end
|
150
|
+
|
151
|
+
def test_cancel_after_without_block
|
152
|
+
t0 = Time.now
|
153
|
+
f = cancel_after(0.01)
|
154
|
+
assert_kind_of Fiber, f
|
155
|
+
assert_equal Fiber.current, f.parent
|
156
|
+
assert_raises Polyphony::Cancel do
|
157
|
+
sleep 1
|
158
|
+
end
|
159
|
+
t1 = Time.now
|
160
|
+
assert t1 - t0 < 0.02
|
161
|
+
end
|
124
162
|
end
|
125
163
|
|
164
|
+
|
126
165
|
class SpinLoopTest < MiniTest::Test
|
127
166
|
def test_spin_loop
|
128
167
|
buffer = []
|
data/test/test_kernel.rb
CHANGED
@@ -4,20 +4,18 @@ require_relative 'helper'
|
|
4
4
|
|
5
5
|
class KernelTest < MiniTest::Test
|
6
6
|
def test_system_method
|
7
|
+
fn = '/tmp/test_system_method'
|
8
|
+
FileUtils.rm(fn) rescue nil
|
9
|
+
|
7
10
|
counter = 0
|
8
11
|
timer = spin { throttled_loop(200) { counter += 1 } }
|
9
12
|
|
10
13
|
system('sleep 0.01')
|
11
14
|
assert(counter >= 2)
|
12
15
|
|
13
|
-
|
14
|
-
|
15
|
-
$stdout = o
|
16
|
-
system('echo "hello"')
|
17
|
-
o.close
|
18
|
-
assert_equal "hello\n", i.read
|
16
|
+
system('echo "hello" > ' + fn)
|
17
|
+
assert_equal "hello\n", IO.read(fn)
|
19
18
|
ensure
|
20
|
-
$stdout = orig_stdout
|
21
19
|
timer&.stop
|
22
20
|
end
|
23
21
|
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'helper'
|
4
|
+
|
5
|
+
class ProcessSupervisionTest < MiniTest::Test
|
6
|
+
def test_process_supervisor_with_block
|
7
|
+
i, o = IO.pipe
|
8
|
+
|
9
|
+
f = spin do
|
10
|
+
Polyphony.watch_process do
|
11
|
+
i.close
|
12
|
+
sleep 5
|
13
|
+
ensure
|
14
|
+
o << 'foo'
|
15
|
+
o.close
|
16
|
+
end
|
17
|
+
supervise(on_error: :restart)
|
18
|
+
end
|
19
|
+
|
20
|
+
sleep 0.05
|
21
|
+
f.terminate
|
22
|
+
f.await
|
23
|
+
|
24
|
+
o.close
|
25
|
+
msg = i.read
|
26
|
+
i.close
|
27
|
+
assert_equal 'foo', msg
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_process_supervisor_with_cmd
|
31
|
+
fn = '/tmp/test_process_supervisor_with_cmd'
|
32
|
+
FileUtils.rm(fn) rescue nil
|
33
|
+
|
34
|
+
f = spin do
|
35
|
+
Polyphony.watch_process("echo foo >> #{fn}")
|
36
|
+
supervise(on_error: :restart)
|
37
|
+
end
|
38
|
+
|
39
|
+
sleep 0.05
|
40
|
+
f.terminate
|
41
|
+
f.await
|
42
|
+
|
43
|
+
assert_equal "foo\n", IO.read(fn)
|
44
|
+
|
45
|
+
end
|
46
|
+
end
|
data/test/test_signal.rb
CHANGED
@@ -44,11 +44,10 @@ class SignalTrapTest < Minitest::Test
|
|
44
44
|
i.close
|
45
45
|
spin do
|
46
46
|
spin do
|
47
|
-
sleep
|
47
|
+
sleep 5
|
48
48
|
rescue ::Interrupt => e
|
49
|
-
# the signal
|
49
|
+
# the signal should be raised only in the main fiber
|
50
50
|
o.puts "1-interrupt"
|
51
|
-
raise e
|
52
51
|
end.await
|
53
52
|
end.await
|
54
53
|
rescue ::Interrupt => e
|
@@ -0,0 +1,103 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'helper'
|
4
|
+
|
5
|
+
class SuperviseTest < MiniTest::Test
|
6
|
+
def test_supervise
|
7
|
+
p = spin { supervise }
|
8
|
+
snooze
|
9
|
+
f1 = p.spin { receive }
|
10
|
+
f2 = p.spin { receive }
|
11
|
+
|
12
|
+
snooze
|
13
|
+
assert_equal p.state, :waiting
|
14
|
+
f1 << 'foo'
|
15
|
+
f1.await
|
16
|
+
snooze
|
17
|
+
|
18
|
+
assert_equal :waiting, p.state
|
19
|
+
assert_equal :waiting, f2.state
|
20
|
+
|
21
|
+
f2 << 'bar'
|
22
|
+
f2.await
|
23
|
+
snooze
|
24
|
+
|
25
|
+
assert_equal :waiting, p.state
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_supervise_with_restart
|
29
|
+
watcher = spin { receive }
|
30
|
+
parent = spin { supervise(restart: true, watcher: watcher) }
|
31
|
+
snooze
|
32
|
+
|
33
|
+
buffer = []
|
34
|
+
f1 = parent.spin do
|
35
|
+
buffer << 'f1'
|
36
|
+
end
|
37
|
+
|
38
|
+
f1.await
|
39
|
+
assert_equal ['f1'], buffer
|
40
|
+
watcher.await
|
41
|
+
assert_equal ['f1', 'f1'], buffer
|
42
|
+
end
|
43
|
+
|
44
|
+
def test_supervise_with_restart_on_error
|
45
|
+
parent = spin { supervise(restart: true) }
|
46
|
+
snooze
|
47
|
+
|
48
|
+
buffer = []
|
49
|
+
f1 = parent.spin do
|
50
|
+
buffer << 'f1'
|
51
|
+
buffer << receive
|
52
|
+
end
|
53
|
+
|
54
|
+
snooze
|
55
|
+
assert_equal ['f1'], buffer
|
56
|
+
|
57
|
+
f1.raise 'foo'
|
58
|
+
|
59
|
+
3.times { snooze }
|
60
|
+
|
61
|
+
assert_equal ['f1', 'f1'], buffer
|
62
|
+
assert_equal :dead, f1.state
|
63
|
+
|
64
|
+
# f1 should have been restarted by supervisor
|
65
|
+
f1 = parent.children.first
|
66
|
+
assert_kind_of Fiber, f1
|
67
|
+
|
68
|
+
f1 << 'foo'
|
69
|
+
f1.await
|
70
|
+
|
71
|
+
assert_equal ['f1', 'f1', 'foo'], buffer
|
72
|
+
end
|
73
|
+
|
74
|
+
def test_supervisor_termination
|
75
|
+
f = nil
|
76
|
+
p = spin do
|
77
|
+
f = spin { sleep 1 }
|
78
|
+
supervise
|
79
|
+
end
|
80
|
+
sleep 0.01
|
81
|
+
|
82
|
+
p.terminate
|
83
|
+
p.await
|
84
|
+
|
85
|
+
assert :dead, f.state
|
86
|
+
assert :dead, p.state
|
87
|
+
end
|
88
|
+
|
89
|
+
def test_supervisor_termination_with_restart
|
90
|
+
f = nil
|
91
|
+
p = spin do
|
92
|
+
f = spin { sleep 1 }
|
93
|
+
supervise(restart: true)
|
94
|
+
end
|
95
|
+
sleep 0.01
|
96
|
+
|
97
|
+
p.terminate
|
98
|
+
p.await
|
99
|
+
|
100
|
+
assert :dead, f.state
|
101
|
+
assert :dead, p.state
|
102
|
+
end
|
103
|
+
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.34'
|
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-03-
|
11
|
+
date: 2020-03-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: modulation
|
@@ -254,12 +254,30 @@ files:
|
|
254
254
|
- README.md
|
255
255
|
- Rakefile
|
256
256
|
- TODO.md
|
257
|
+
- bin/polyphony-debug
|
257
258
|
- docs/_config.yml
|
258
259
|
- docs/_includes/nav.html
|
259
260
|
- docs/_includes/prevnext.html
|
260
261
|
- docs/_layouts/default.html
|
261
262
|
- docs/_sass/custom/custom.scss
|
262
263
|
- docs/_sass/overrides.scss
|
264
|
+
- docs/api-reference.md
|
265
|
+
- docs/api-reference/exception.md
|
266
|
+
- docs/api-reference/fiber.md
|
267
|
+
- docs/api-reference/io.md
|
268
|
+
- docs/api-reference/object.md
|
269
|
+
- docs/api-reference/polyphony-baseexception.md
|
270
|
+
- docs/api-reference/polyphony-cancel.md
|
271
|
+
- docs/api-reference/polyphony-moveon.md
|
272
|
+
- docs/api-reference/polyphony-net.md
|
273
|
+
- docs/api-reference/polyphony-process.md
|
274
|
+
- docs/api-reference/polyphony-resourcepool.md
|
275
|
+
- docs/api-reference/polyphony-restart.md
|
276
|
+
- docs/api-reference/polyphony-terminate.md
|
277
|
+
- docs/api-reference/polyphony-threadpool.md
|
278
|
+
- docs/api-reference/polyphony-throttler.md
|
279
|
+
- docs/api-reference/polyphony.md
|
280
|
+
- docs/api-reference/thread.md
|
263
281
|
- docs/assets/img/echo-fibers.svg
|
264
282
|
- docs/assets/img/sleeping-fiber.svg
|
265
283
|
- docs/faq.md
|
@@ -287,11 +305,15 @@ files:
|
|
287
305
|
- examples/core/01-spinning-up-fibers.rb
|
288
306
|
- examples/core/02-awaiting-fibers.rb
|
289
307
|
- examples/core/03-interrupting.rb
|
308
|
+
- examples/core/forever_sleep.rb
|
290
309
|
- examples/core/xx-at_exit.rb
|
310
|
+
- examples/core/xx-caller.rb
|
291
311
|
- examples/core/xx-channels.rb
|
292
312
|
- examples/core/xx-deadlock.rb
|
293
313
|
- examples/core/xx-deferring-an-operation.rb
|
294
314
|
- examples/core/xx-erlang-style-genserver.rb
|
315
|
+
- examples/core/xx-exception-backtrace.rb
|
316
|
+
- examples/core/xx-fork-spin.rb
|
295
317
|
- examples/core/xx-fork-terminate.rb
|
296
318
|
- examples/core/xx-forking.rb
|
297
319
|
- examples/core/xx-move_on.rb
|
@@ -304,9 +326,11 @@ files:
|
|
304
326
|
- examples/core/xx-sleep-forever.rb
|
305
327
|
- examples/core/xx-sleeping.rb
|
306
328
|
- examples/core/xx-snooze-starve.rb
|
329
|
+
- examples/core/xx-spin-fork.rb
|
307
330
|
- examples/core/xx-spin_error_backtrace.rb
|
308
331
|
- examples/core/xx-state-machine.rb
|
309
332
|
- examples/core/xx-stop.rb
|
333
|
+
- examples/core/xx-supervise-process.rb
|
310
334
|
- examples/core/xx-supervisors.rb
|
311
335
|
- examples/core/xx-thread-selector-sleep.rb
|
312
336
|
- examples/core/xx-thread-selector-snooze.rb
|
@@ -381,6 +405,7 @@ files:
|
|
381
405
|
- lib/polyphony/adapters/fs.rb
|
382
406
|
- lib/polyphony/adapters/irb.rb
|
383
407
|
- lib/polyphony/adapters/postgres.rb
|
408
|
+
- lib/polyphony/adapters/process.rb
|
384
409
|
- lib/polyphony/adapters/redis.rb
|
385
410
|
- lib/polyphony/adapters/trace.rb
|
386
411
|
- lib/polyphony/core/channel.rb
|
@@ -410,8 +435,10 @@ files:
|
|
410
435
|
- test/test_global_api.rb
|
411
436
|
- test/test_io.rb
|
412
437
|
- test/test_kernel.rb
|
438
|
+
- test/test_process_supervision.rb
|
413
439
|
- test/test_resource_pool.rb
|
414
440
|
- test/test_signal.rb
|
441
|
+
- test/test_supervise.rb
|
415
442
|
- test/test_thread.rb
|
416
443
|
- test/test_thread_pool.rb
|
417
444
|
- test/test_throttler.rb
|