polyphony 0.29 → 0.30
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/.gitignore +1 -0
- data/CHANGELOG.md +14 -0
- data/Gemfile.lock +1 -1
- data/TODO.md +15 -10
- data/docs/getting-started/tutorial.md +3 -3
- data/docs/index.md +2 -3
- data/docs/{technical-overview → main-concepts}/concurrency.md +62 -15
- data/docs/{technical-overview → main-concepts}/design-principles.md +21 -8
- data/docs/{technical-overview → main-concepts}/exception-handling.md +80 -38
- data/docs/{technical-overview → main-concepts}/extending.md +4 -3
- data/docs/{technical-overview → main-concepts}/fiber-scheduling.md +3 -3
- data/docs/{technical-overview.md → main-concepts.md} +2 -2
- data/examples/core/xx-at_exit.rb +29 -0
- data/examples/core/xx-fork-terminate.rb +27 -0
- data/examples/core/xx-pingpong.rb +18 -0
- data/examples/core/xx-stop.rb +20 -0
- data/ext/gyro/async.c +1 -1
- data/ext/gyro/extconf.rb +0 -3
- data/ext/gyro/gyro.c +7 -8
- data/ext/gyro/gyro.h +2 -0
- data/ext/gyro/queue.c +6 -6
- data/ext/gyro/selector.c +32 -1
- data/ext/gyro/thread.c +55 -9
- data/ext/gyro/timer.c +1 -0
- data/lib/polyphony/core/exceptions.rb +4 -1
- data/lib/polyphony/core/global_api.rb +1 -6
- data/lib/polyphony/core/thread_pool.rb +3 -3
- data/lib/polyphony/extensions/core.rb +7 -1
- data/lib/polyphony/extensions/fiber.rb +159 -72
- data/lib/polyphony/extensions/io.rb +2 -4
- data/lib/polyphony/extensions/openssl.rb +0 -17
- data/lib/polyphony/extensions/thread.rb +46 -22
- data/lib/polyphony/version.rb +1 -1
- data/lib/polyphony.rb +20 -18
- data/test/coverage.rb +1 -1
- data/test/helper.rb +7 -3
- data/test/test_fiber.rb +285 -72
- data/test/test_global_api.rb +7 -52
- data/test/test_io.rb +8 -0
- data/test/test_signal.rb +1 -0
- data/test/test_thread.rb +76 -56
- data/test/test_thread_pool.rb +27 -5
- data/test/test_throttler.rb +1 -0
- metadata +12 -12
- data/lib/polyphony/core/supervisor.rb +0 -114
- data/lib/polyphony/line_reader.rb +0 -82
- data/test/test_gyro.rb +0 -25
- data/test/test_supervisor.rb +0 -180
data/test/test_fiber.rb
CHANGED
@@ -5,7 +5,7 @@ require_relative 'helper'
|
|
5
5
|
class FiberTest < MiniTest::Test
|
6
6
|
def test_spin_initial_state
|
7
7
|
result = nil
|
8
|
-
f = Fiber.spin { result = 42 }
|
8
|
+
f = Fiber.current.spin { result = 42 }
|
9
9
|
assert_nil result
|
10
10
|
f.await
|
11
11
|
assert_equal 42, result
|
@@ -15,7 +15,7 @@ class FiberTest < MiniTest::Test
|
|
15
15
|
|
16
16
|
def test_await
|
17
17
|
result = nil
|
18
|
-
f = Fiber.spin do
|
18
|
+
f = Fiber.current.spin do
|
19
19
|
snooze
|
20
20
|
result = 42
|
21
21
|
end
|
@@ -25,6 +25,49 @@ class FiberTest < MiniTest::Test
|
|
25
25
|
f&.stop
|
26
26
|
end
|
27
27
|
|
28
|
+
def test_await_from_multiple_fibers
|
29
|
+
buffer = []
|
30
|
+
f1 = spin {
|
31
|
+
sleep 0.02
|
32
|
+
buffer << :foo
|
33
|
+
}
|
34
|
+
f2 = spin {
|
35
|
+
f1.await
|
36
|
+
buffer << :bar
|
37
|
+
}
|
38
|
+
f3 = spin {
|
39
|
+
f1.await
|
40
|
+
buffer << :baz
|
41
|
+
}
|
42
|
+
Fiber.await(f2, f3)
|
43
|
+
assert_equal [:foo, :bar, :baz], buffer
|
44
|
+
assert_equal 0, Fiber.current.children.size
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_await_from_multiple_fibers_with_interruption
|
48
|
+
buffer = []
|
49
|
+
f1 = spin {
|
50
|
+
sleep 0.02
|
51
|
+
buffer << :foo
|
52
|
+
}
|
53
|
+
f2 = spin {
|
54
|
+
f1.await
|
55
|
+
buffer << :bar
|
56
|
+
}
|
57
|
+
f3 = spin {
|
58
|
+
f1.await
|
59
|
+
buffer << :baz
|
60
|
+
}
|
61
|
+
snooze
|
62
|
+
f2.stop
|
63
|
+
f3.stop
|
64
|
+
snooze
|
65
|
+
f1.stop
|
66
|
+
|
67
|
+
snooze
|
68
|
+
assert_equal [], Fiber.current.children
|
69
|
+
end
|
70
|
+
|
28
71
|
def test_schedule
|
29
72
|
values = []
|
30
73
|
fibers = (0..2).map { |i| spin { suspend; values << i } }
|
@@ -74,7 +117,7 @@ class FiberTest < MiniTest::Test
|
|
74
117
|
async.signal!(:foo)
|
75
118
|
end
|
76
119
|
|
77
|
-
result = move_on_after(
|
120
|
+
result = move_on_after(1) { async.await }
|
78
121
|
|
79
122
|
assert_equal :foo, result
|
80
123
|
ensure
|
@@ -86,12 +129,12 @@ class FiberTest < MiniTest::Test
|
|
86
129
|
Fiber.current.tag = :foo
|
87
130
|
assert_equal :foo, Fiber.current.tag
|
88
131
|
|
89
|
-
f = Fiber.spin(:bar) { }
|
132
|
+
f = Fiber.current.spin(:bar) { }
|
90
133
|
assert_equal :bar, f.tag
|
91
134
|
end
|
92
135
|
|
93
136
|
def test_await_return_value
|
94
|
-
f = Fiber.spin { %i[foo bar] }
|
137
|
+
f = Fiber.current.spin { %i[foo bar] }
|
95
138
|
assert_equal %i[foo bar], f.await
|
96
139
|
ensure
|
97
140
|
f&.stop
|
@@ -99,7 +142,7 @@ class FiberTest < MiniTest::Test
|
|
99
142
|
|
100
143
|
def test_await_with_error
|
101
144
|
result = nil
|
102
|
-
f = Fiber.spin { raise 'foo' }
|
145
|
+
f = Fiber.current.spin { raise 'foo' }
|
103
146
|
begin
|
104
147
|
result = f.await
|
105
148
|
rescue Exception => e
|
@@ -114,7 +157,7 @@ class FiberTest < MiniTest::Test
|
|
114
157
|
def test_raise
|
115
158
|
result = []
|
116
159
|
error = nil
|
117
|
-
f = Fiber.spin do
|
160
|
+
f = Fiber.current.spin do
|
118
161
|
result << 1
|
119
162
|
2.times { snooze }
|
120
163
|
result << 2
|
@@ -139,7 +182,7 @@ class FiberTest < MiniTest::Test
|
|
139
182
|
def test_raise_with_error_class
|
140
183
|
result = []
|
141
184
|
error = nil
|
142
|
-
f = Fiber.spin do
|
185
|
+
f = Fiber.current.spin do
|
143
186
|
result << 1
|
144
187
|
2.times { snooze }
|
145
188
|
result << 2
|
@@ -161,7 +204,7 @@ class FiberTest < MiniTest::Test
|
|
161
204
|
def test_raise_with_error_class_and_message
|
162
205
|
result = []
|
163
206
|
error = nil
|
164
|
-
f = Fiber.spin do
|
207
|
+
f = Fiber.current.spin do
|
165
208
|
result << 1
|
166
209
|
2.times { snooze }
|
167
210
|
result << 2
|
@@ -184,7 +227,7 @@ class FiberTest < MiniTest::Test
|
|
184
227
|
def test_raise_with_message
|
185
228
|
result = []
|
186
229
|
error = nil
|
187
|
-
f = Fiber.spin do
|
230
|
+
f = Fiber.current.spin do
|
188
231
|
result << 1
|
189
232
|
2.times { snooze }
|
190
233
|
result << 2
|
@@ -207,7 +250,7 @@ class FiberTest < MiniTest::Test
|
|
207
250
|
def test_raise_with_exception
|
208
251
|
result = []
|
209
252
|
error = nil
|
210
|
-
f = Fiber.spin do
|
253
|
+
f = Fiber.current.spin do
|
211
254
|
result << 1
|
212
255
|
2.times { snooze }
|
213
256
|
result << 2
|
@@ -230,7 +273,7 @@ class FiberTest < MiniTest::Test
|
|
230
273
|
def test_cancel
|
231
274
|
result = []
|
232
275
|
error = nil
|
233
|
-
f = Fiber.spin do
|
276
|
+
f = Fiber.current.spin do
|
234
277
|
result << 1
|
235
278
|
2.times { snooze }
|
236
279
|
result << 2
|
@@ -252,7 +295,7 @@ class FiberTest < MiniTest::Test
|
|
252
295
|
def test_interrupt
|
253
296
|
# that is, stopped without exception
|
254
297
|
result = []
|
255
|
-
f = Fiber.spin do
|
298
|
+
f = Fiber.current.spin do
|
256
299
|
result << 1
|
257
300
|
2.times { snooze }
|
258
301
|
result << 2
|
@@ -267,10 +310,39 @@ class FiberTest < MiniTest::Test
|
|
267
310
|
f&.stop
|
268
311
|
end
|
269
312
|
|
313
|
+
def test_terminate
|
314
|
+
buffer = []
|
315
|
+
f = spin do
|
316
|
+
buffer << :foo
|
317
|
+
sleep 1
|
318
|
+
buffer << :bar
|
319
|
+
rescue Polyphony::Terminate
|
320
|
+
buffer << :terminate
|
321
|
+
end
|
322
|
+
snooze
|
323
|
+
f.terminate
|
324
|
+
snooze
|
325
|
+
assert_equal [:foo, :terminate], buffer
|
326
|
+
end
|
327
|
+
|
328
|
+
def test_interrupt_timer
|
329
|
+
result = []
|
330
|
+
f = Fiber.current.spin do
|
331
|
+
result << :start
|
332
|
+
t = Gyro::Timer.new(1, 0)
|
333
|
+
result << t.await
|
334
|
+
end
|
335
|
+
snooze
|
336
|
+
f.interrupt
|
337
|
+
f.join
|
338
|
+
|
339
|
+
assert_equal [:start], result
|
340
|
+
end
|
341
|
+
|
270
342
|
def test_stop
|
271
343
|
# that is, stopped without exception
|
272
344
|
result = []
|
273
|
-
f = Fiber.spin do
|
345
|
+
f = Fiber.current.spin do
|
274
346
|
result << 1
|
275
347
|
2.times { snooze }
|
276
348
|
result << 2
|
@@ -287,7 +359,7 @@ class FiberTest < MiniTest::Test
|
|
287
359
|
|
288
360
|
def test_interrupt_before_start
|
289
361
|
result = []
|
290
|
-
f = Fiber.spin do
|
362
|
+
f = Fiber.current.spin do
|
291
363
|
result << 1
|
292
364
|
end
|
293
365
|
f.interrupt(42)
|
@@ -336,12 +408,21 @@ class FiberTest < MiniTest::Test
|
|
336
408
|
snooze while counter < 3
|
337
409
|
assert_equal :waiting, f.state
|
338
410
|
f.stop
|
411
|
+
snooze
|
339
412
|
assert_equal :dead, f.state
|
340
413
|
ensure
|
341
414
|
f&.stop
|
342
415
|
end
|
343
416
|
|
344
|
-
def
|
417
|
+
def test_main?
|
418
|
+
f = spin {
|
419
|
+
sleep
|
420
|
+
}
|
421
|
+
assert_nil f.main?
|
422
|
+
assert_equal true, Fiber.current.main?
|
423
|
+
end
|
424
|
+
|
425
|
+
def test_exception_propagation
|
345
426
|
# error is propagated to calling fiber
|
346
427
|
raised_error = nil
|
347
428
|
spin do
|
@@ -358,22 +439,6 @@ class FiberTest < MiniTest::Test
|
|
358
439
|
assert_equal 'foo', raised_error.message
|
359
440
|
end
|
360
441
|
|
361
|
-
def test_exception_bubling_for_orphan_fiber
|
362
|
-
raised_error = nil
|
363
|
-
spin do
|
364
|
-
spin do
|
365
|
-
snooze
|
366
|
-
raise 'bar'
|
367
|
-
end
|
368
|
-
end
|
369
|
-
suspend
|
370
|
-
rescue Exception => e
|
371
|
-
raised_error = e
|
372
|
-
ensure
|
373
|
-
assert raised_error
|
374
|
-
assert_equal 'bar', raised_error.message
|
375
|
-
end
|
376
|
-
|
377
442
|
def test_await_multiple_fibers
|
378
443
|
f1 = spin { sleep 0.01; :foo }
|
379
444
|
f2 = spin { sleep 0.01; :bar }
|
@@ -399,7 +464,7 @@ class FiberTest < MiniTest::Test
|
|
399
464
|
f2 = spin { sleep 0.03; buffer << :bar; :bar }
|
400
465
|
f3 = spin { sleep 0.05; buffer << :baz; :baz }
|
401
466
|
|
402
|
-
|
467
|
+
selected, result = Fiber.select(f1, f2, f3)
|
403
468
|
assert_equal :foo, result
|
404
469
|
assert_equal f1, selected
|
405
470
|
assert_equal [:foo], buffer
|
@@ -446,18 +511,16 @@ class FiberTest < MiniTest::Test
|
|
446
511
|
assert !f.running?
|
447
512
|
end
|
448
513
|
|
449
|
-
def
|
450
|
-
assert_equal
|
451
|
-
assert_equal [Fiber.current], Fiber.list
|
514
|
+
def test_children
|
515
|
+
assert_equal [], Fiber.current.children
|
452
516
|
|
453
517
|
f = spin { sleep 1 }
|
454
518
|
snooze
|
455
|
-
assert_equal
|
456
|
-
assert_equal f, Fiber.list.last
|
519
|
+
assert_equal [f], Fiber.current.children
|
457
520
|
|
458
521
|
f.stop
|
459
522
|
snooze
|
460
|
-
assert_equal
|
523
|
+
assert_equal [], Fiber.current.children
|
461
524
|
end
|
462
525
|
|
463
526
|
def test_inspect
|
@@ -486,60 +549,109 @@ class FiberTest < MiniTest::Test
|
|
486
549
|
end
|
487
550
|
|
488
551
|
def test_system_exit_in_fiber
|
489
|
-
|
490
|
-
|
491
|
-
|
492
|
-
f1 = spin do
|
493
|
-
f2 = spin { raise SystemExit }
|
494
|
-
suspend
|
495
|
-
rescue Exception => parent_error
|
552
|
+
error = nil
|
553
|
+
spin do
|
554
|
+
spin { raise SystemExit }.await
|
496
555
|
end
|
497
556
|
|
498
557
|
begin
|
499
558
|
suspend
|
500
|
-
rescue Exception =>
|
559
|
+
rescue Exception => error
|
501
560
|
end
|
502
561
|
|
503
|
-
|
504
|
-
assert_kind_of SystemExit, main_fiber_error
|
562
|
+
assert_kind_of SystemExit, error
|
505
563
|
end
|
506
564
|
|
507
565
|
def test_interrupt_in_fiber
|
508
|
-
|
509
|
-
|
510
|
-
|
511
|
-
f1 = spin do
|
512
|
-
f2 = spin { raise Interrupt }
|
513
|
-
suspend
|
514
|
-
rescue Exception => parent_error
|
566
|
+
error = nil
|
567
|
+
spin do
|
568
|
+
spin { raise Interrupt }.await
|
515
569
|
end
|
516
570
|
|
517
571
|
begin
|
518
572
|
suspend
|
519
|
-
rescue Exception =>
|
573
|
+
rescue Exception => error
|
520
574
|
end
|
521
575
|
|
522
|
-
|
523
|
-
assert_kind_of Interrupt, main_fiber_error
|
576
|
+
assert_kind_of Interrupt, error
|
524
577
|
end
|
525
578
|
|
526
579
|
def test_signal_exception_in_fiber
|
527
|
-
|
528
|
-
|
529
|
-
|
530
|
-
f1 = spin do
|
531
|
-
f2 = spin { raise SignalException.new('HUP') }
|
532
|
-
suspend
|
533
|
-
rescue Exception => parent_error
|
580
|
+
error = nil
|
581
|
+
spin do
|
582
|
+
spin { raise SignalException.new('HUP') }.await
|
534
583
|
end
|
535
584
|
|
536
585
|
begin
|
537
586
|
suspend
|
538
|
-
rescue Exception =>
|
587
|
+
rescue Exception => error
|
539
588
|
end
|
540
589
|
|
541
|
-
|
542
|
-
|
590
|
+
assert_kind_of SignalException, error
|
591
|
+
end
|
592
|
+
|
593
|
+
def test_signal_handling_int
|
594
|
+
i, o = IO.pipe
|
595
|
+
pid = Polyphony.fork do
|
596
|
+
f = spin { sleep 100 }
|
597
|
+
begin
|
598
|
+
i.close
|
599
|
+
f.await
|
600
|
+
rescue Exception => e
|
601
|
+
o << e.class.name
|
602
|
+
o.close
|
603
|
+
end
|
604
|
+
end
|
605
|
+
sleep 0.1
|
606
|
+
f = spin { Gyro::Child.new(pid).await }
|
607
|
+
o.close
|
608
|
+
Process.kill('INT', pid)
|
609
|
+
f.await
|
610
|
+
klass = i.read
|
611
|
+
o.close
|
612
|
+
assert_equal 'Interrupt', klass
|
613
|
+
end
|
614
|
+
|
615
|
+
def test_signal_handling_term
|
616
|
+
i, o = IO.pipe
|
617
|
+
pid = Polyphony.fork do
|
618
|
+
f = spin { sleep 100 }
|
619
|
+
begin
|
620
|
+
i.close
|
621
|
+
f.await
|
622
|
+
rescue Exception => e
|
623
|
+
o << e.class.name
|
624
|
+
o.close
|
625
|
+
end
|
626
|
+
end
|
627
|
+
sleep 0.1
|
628
|
+
f = spin { Gyro::Child.new(pid).await }
|
629
|
+
o.close
|
630
|
+
Process.kill('TERM', pid)
|
631
|
+
f.await
|
632
|
+
klass = i.read
|
633
|
+
o.close
|
634
|
+
assert_equal 'SystemExit', klass
|
635
|
+
end
|
636
|
+
|
637
|
+
def test_main_fiber_child_termination_after_fork
|
638
|
+
i, o = IO.pipe
|
639
|
+
pid = Polyphony.fork do
|
640
|
+
i.close
|
641
|
+
f = spin do
|
642
|
+
sleep 100
|
643
|
+
rescue Exception => e
|
644
|
+
o << e.class.to_s
|
645
|
+
o.close
|
646
|
+
end
|
647
|
+
snooze
|
648
|
+
ensure
|
649
|
+
end
|
650
|
+
o.close
|
651
|
+
Gyro::Child.new(pid).await
|
652
|
+
klass = i.read
|
653
|
+
i.close
|
654
|
+
assert_equal 'Polyphony::Terminate', klass
|
543
655
|
end
|
544
656
|
end
|
545
657
|
|
@@ -552,7 +664,7 @@ class MailboxTest < MiniTest::Test
|
|
552
664
|
|
553
665
|
3.times do |i|
|
554
666
|
f << i
|
555
|
-
|
667
|
+
sleep 0
|
556
668
|
end
|
557
669
|
|
558
670
|
assert_equal [0, 1, 2], msgs
|
@@ -568,7 +680,7 @@ class MailboxTest < MiniTest::Test
|
|
568
680
|
|
569
681
|
3.times { |i| f << i }
|
570
682
|
|
571
|
-
|
683
|
+
sleep 0
|
572
684
|
|
573
685
|
assert_equal [0, 1, 2], msgs
|
574
686
|
ensure
|
@@ -588,10 +700,10 @@ class MailboxTest < MiniTest::Test
|
|
588
700
|
end
|
589
701
|
|
590
702
|
def test_cross_thread_send_receive
|
591
|
-
skip "There's currently a race condition in cross-thread send/receive. We're going to rewrite it in C"
|
592
703
|
ping_receive_buffer = []
|
593
704
|
pong_receive_buffer = []
|
594
705
|
pong = Thread.new do
|
706
|
+
sleep 0.05
|
595
707
|
loop do
|
596
708
|
peer, data = receive
|
597
709
|
pong_receive_buffer << data
|
@@ -600,6 +712,7 @@ class MailboxTest < MiniTest::Test
|
|
600
712
|
end
|
601
713
|
|
602
714
|
ping = Thread.new do
|
715
|
+
sleep 0.05
|
603
716
|
3.times do
|
604
717
|
pong << [Fiber.current, 'ping']
|
605
718
|
data = receive
|
@@ -613,4 +726,104 @@ class MailboxTest < MiniTest::Test
|
|
613
726
|
assert_equal %w{pong pong pong}, ping_receive_buffer
|
614
727
|
assert_equal %w{ping ping ping}, pong_receive_buffer
|
615
728
|
end
|
729
|
+
|
730
|
+
def test_message_queueing
|
731
|
+
messages = []
|
732
|
+
f = spin do
|
733
|
+
loop {
|
734
|
+
msg = receive
|
735
|
+
break if msg == 'stop'
|
736
|
+
|
737
|
+
messages << msg
|
738
|
+
}
|
739
|
+
end
|
740
|
+
|
741
|
+
100.times { f << 'foo' }
|
742
|
+
f << 'stop'
|
743
|
+
|
744
|
+
f.await
|
745
|
+
assert_equal ['foo'] * 100, messages
|
746
|
+
end
|
616
747
|
end
|
748
|
+
|
749
|
+
class FiberControlTest < MiniTest::Test
|
750
|
+
def test_await_multiple
|
751
|
+
f1 = spin {
|
752
|
+
snooze
|
753
|
+
:foo
|
754
|
+
}
|
755
|
+
f2 = spin {
|
756
|
+
snooze
|
757
|
+
:bar
|
758
|
+
}
|
759
|
+
result = Fiber.await(f1, f2)
|
760
|
+
assert_equal [:foo, :bar], result
|
761
|
+
end
|
762
|
+
|
763
|
+
def test_await_multiple_with_raised_error
|
764
|
+
f1 = spin {
|
765
|
+
snooze
|
766
|
+
raise 'foo'
|
767
|
+
}
|
768
|
+
f2 = spin {
|
769
|
+
snooze
|
770
|
+
:bar
|
771
|
+
}
|
772
|
+
f3 = spin {
|
773
|
+
sleep 3
|
774
|
+
}
|
775
|
+
error = nil
|
776
|
+
begin
|
777
|
+
Fiber.await(f1, f2, f3)
|
778
|
+
rescue => error
|
779
|
+
end
|
780
|
+
assert_kind_of RuntimeError, error
|
781
|
+
assert_equal 'foo', error.message
|
782
|
+
|
783
|
+
assert_equal :dead, f1.state
|
784
|
+
assert_equal :dead, f2.state
|
785
|
+
assert_equal :dead, f3.state
|
786
|
+
end
|
787
|
+
|
788
|
+
def test_await_multiple_with_interruption
|
789
|
+
f1 = spin { sleep 0.01; :foo }
|
790
|
+
f2 = spin { sleep 1; :bar }
|
791
|
+
spin { snooze; f2.interrupt(:baz) }
|
792
|
+
result = Fiber.await(f1, f2)
|
793
|
+
assert_equal [:foo, :baz], result
|
794
|
+
end
|
795
|
+
|
796
|
+
def test_select
|
797
|
+
buffer = []
|
798
|
+
f1 = spin { snooze; buffer << :foo; :foo }
|
799
|
+
f2 = spin { :bar }
|
800
|
+
result = Fiber.select(f1, f2)
|
801
|
+
assert_equal [f2, :bar], result
|
802
|
+
assert_equal [:foo], buffer
|
803
|
+
assert_equal :dead, f1.state
|
804
|
+
end
|
805
|
+
|
806
|
+
def test_select_with_raised_error
|
807
|
+
f1 = spin { snooze; raise 'foo' }
|
808
|
+
f2 = spin { sleep 3 }
|
809
|
+
|
810
|
+
result = nil
|
811
|
+
begin
|
812
|
+
result = Fiber.select(f1, f2)
|
813
|
+
rescue => result
|
814
|
+
end
|
815
|
+
|
816
|
+
assert_kind_of RuntimeError, result
|
817
|
+
assert_equal 'foo', result.message
|
818
|
+
assert_equal :dead, f1.state
|
819
|
+
assert_equal :dead, f2.state
|
820
|
+
end
|
821
|
+
|
822
|
+
def test_select_with_interruption
|
823
|
+
f1 = spin { sleep 0.01; :foo }
|
824
|
+
f2 = spin { sleep 1; :bar }
|
825
|
+
spin { snooze; f2.interrupt(:baz) }
|
826
|
+
result = Fiber.select(f1, f2)
|
827
|
+
assert_equal [f2, :baz], result
|
828
|
+
end
|
829
|
+
end
|
data/test/test_global_api.rb
CHANGED
@@ -15,7 +15,7 @@ class SpinTest < MiniTest::Test
|
|
15
15
|
|
16
16
|
def test_that_spin_accepts_fiber_argument
|
17
17
|
result = nil
|
18
|
-
fiber = Fiber.spin { result = 42 }
|
18
|
+
fiber = Fiber.current.spin { result = 42 }
|
19
19
|
|
20
20
|
assert_nil result
|
21
21
|
suspend
|
@@ -128,51 +128,6 @@ class CancelScopeTest < Minitest::Test
|
|
128
128
|
# end
|
129
129
|
end
|
130
130
|
|
131
|
-
class SupervisorTest < MiniTest::Test
|
132
|
-
def sleep_and_set(ctx, idx)
|
133
|
-
proc do
|
134
|
-
sleep(0.001 * idx)
|
135
|
-
ctx[idx] = true
|
136
|
-
end
|
137
|
-
end
|
138
|
-
|
139
|
-
def parallel_sleep(ctx)
|
140
|
-
supervise do |s|
|
141
|
-
(1..3).each { |idx| s.spin(&sleep_and_set(ctx, idx)) }
|
142
|
-
end
|
143
|
-
end
|
144
|
-
|
145
|
-
def test_that_supervisor_waits_for_all_nested_fibers_to_complete
|
146
|
-
ctx = {}
|
147
|
-
spin do
|
148
|
-
parallel_sleep(ctx)
|
149
|
-
end
|
150
|
-
suspend
|
151
|
-
assert ctx[1]
|
152
|
-
assert ctx[2]
|
153
|
-
assert ctx[3]
|
154
|
-
end
|
155
|
-
|
156
|
-
def test_that_supervisor_can_add_fibers_after_having_started
|
157
|
-
result = []
|
158
|
-
spin do
|
159
|
-
supervisor = Polyphony::Supervisor.new
|
160
|
-
3.times do |i|
|
161
|
-
spin do
|
162
|
-
sleep(0.001)
|
163
|
-
supervisor.spin do
|
164
|
-
sleep(0.001)
|
165
|
-
result << i
|
166
|
-
end
|
167
|
-
end
|
168
|
-
end
|
169
|
-
supervisor.await
|
170
|
-
end.await
|
171
|
-
|
172
|
-
assert_equal [0, 1, 2], result.sort
|
173
|
-
end
|
174
|
-
end
|
175
|
-
|
176
131
|
class ExceptionTest < MiniTest::Test
|
177
132
|
def test_cross_fiber_backtrace
|
178
133
|
error = nil
|
@@ -191,8 +146,8 @@ class ExceptionTest < MiniTest::Test
|
|
191
146
|
rescue Exception => e
|
192
147
|
frames << 3
|
193
148
|
raise e
|
194
|
-
end
|
195
|
-
5.times {
|
149
|
+
end#.await
|
150
|
+
5.times { snooze }
|
196
151
|
rescue Exception => e
|
197
152
|
error = e
|
198
153
|
ensure
|
@@ -206,10 +161,9 @@ class ExceptionTest < MiniTest::Test
|
|
206
161
|
spin do
|
207
162
|
spin do
|
208
163
|
raise 'foo'
|
209
|
-
end
|
210
|
-
end
|
211
|
-
end
|
212
|
-
4.times { snooze }
|
164
|
+
end.await
|
165
|
+
end.await
|
166
|
+
end.await
|
213
167
|
rescue Exception => e
|
214
168
|
error = e
|
215
169
|
ensure
|
@@ -319,6 +273,7 @@ class MoveOnAfterTest < MiniTest::Test
|
|
319
273
|
snooze
|
320
274
|
assert f.running?
|
321
275
|
f.stop
|
276
|
+
snooze
|
322
277
|
assert !f.running?
|
323
278
|
end
|
324
279
|
|
data/test/test_io.rb
CHANGED
@@ -194,4 +194,12 @@ class IOClassMethodsTest < MiniTest::Test
|
|
194
194
|
ensure
|
195
195
|
$stdout = orig_stdout
|
196
196
|
end
|
197
|
+
|
198
|
+
def test_read_large_file
|
199
|
+
fn = '/tmp/test.txt'
|
200
|
+
File.open(fn, 'w') { |f| f << ('*' * 1e6) }
|
201
|
+
s = IO.read(fn)
|
202
|
+
assert_equal 1e6, s.bytesize
|
203
|
+
assert s == IO.orig_read(fn)
|
204
|
+
end
|
197
205
|
end
|