polyphony 0.43.11 → 0.45.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (143) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +8 -1
  3. data/CHANGELOG.md +40 -0
  4. data/Gemfile.lock +18 -8
  5. data/Rakefile +1 -1
  6. data/TODO.md +22 -9
  7. data/docs/_posts/2020-07-26-polyphony-0.44.md +77 -0
  8. data/docs/api-reference/thread.md +1 -1
  9. data/docs/getting-started/overview.md +14 -14
  10. data/docs/getting-started/tutorial.md +1 -1
  11. data/examples/adapters/redis_client.rb +3 -1
  12. data/examples/adapters/redis_pubsub_perf.rb +11 -8
  13. data/examples/adapters/sequel_mysql.rb +23 -0
  14. data/examples/adapters/sequel_mysql_pool.rb +33 -0
  15. data/examples/adapters/sequel_pg.rb +24 -0
  16. data/examples/core/{02-awaiting-fibers.rb → await.rb} +0 -0
  17. data/examples/core/{xx-channels.rb → channels.rb} +0 -0
  18. data/examples/core/deferring-an-operation.rb +16 -0
  19. data/examples/core/{xx-erlang-style-genserver.rb → erlang-style-genserver.rb} +16 -9
  20. data/examples/core/{xx-forking.rb → forking.rb} +1 -1
  21. data/examples/core/handling-signals.rb +11 -0
  22. data/examples/core/{03-interrupting.rb → interrupt.rb} +0 -0
  23. data/examples/core/{xx-pingpong.rb → pingpong.rb} +7 -5
  24. data/examples/core/{xx-recurrent-timer.rb → recurrent-timer.rb} +1 -1
  25. data/examples/core/{xx-resource_delegate.rb → resource_delegate.rb} +3 -4
  26. data/examples/core/{01-spinning-up-fibers.rb → spin.rb} +1 -1
  27. data/examples/core/{xx-spin_error_backtrace.rb → spin_error_backtrace.rb} +1 -1
  28. data/examples/core/{xx-supervise-process.rb → supervise-process.rb} +8 -5
  29. data/examples/core/supervisor.rb +20 -0
  30. data/examples/core/{xx-thread-sleep.rb → thread-sleep.rb} +0 -0
  31. data/examples/core/{xx-thread_pool.rb → thread_pool.rb} +0 -0
  32. data/examples/core/{xx-throttling.rb → throttling.rb} +0 -0
  33. data/examples/core/{xx-timeout.rb → timeout.rb} +0 -0
  34. data/examples/core/{xx-using-a-mutex.rb → using-a-mutex.rb} +0 -0
  35. data/examples/core/{xx-worker-thread.rb → worker-thread.rb} +2 -2
  36. data/examples/io/{xx-backticks.rb → backticks.rb} +0 -0
  37. data/examples/io/{xx-echo_client.rb → echo_client.rb} +1 -1
  38. data/examples/io/{xx-echo_client_from_stdin.rb → echo_client_from_stdin.rb} +2 -2
  39. data/examples/io/{xx-echo_pipe.rb → echo_pipe.rb} +1 -1
  40. data/examples/io/{xx-echo_server.rb → echo_server.rb} +0 -0
  41. data/examples/io/{xx-echo_server_with_timeout.rb → echo_server_with_timeout.rb} +1 -1
  42. data/examples/io/{xx-echo_stdin.rb → echo_stdin.rb} +0 -0
  43. data/examples/io/{xx-happy-eyeballs.rb → happy-eyeballs.rb} +0 -0
  44. data/examples/io/{xx-httparty.rb → httparty.rb} +4 -13
  45. data/examples/io/{xx-irb.rb → irb.rb} +0 -0
  46. data/examples/io/{xx-net-http.rb → net-http.rb} +0 -0
  47. data/examples/io/{xx-open.rb → open.rb} +0 -0
  48. data/examples/io/pry.rb +18 -0
  49. data/examples/io/rack_server.rb +71 -0
  50. data/examples/io/raw.rb +14 -0
  51. data/examples/io/reline.rb +18 -0
  52. data/examples/io/{xx-system.rb → system.rb} +1 -1
  53. data/examples/io/{xx-tcpserver.rb → tcpserver.rb} +0 -0
  54. data/examples/io/{xx-tcpsocket.rb → tcpsocket.rb} +0 -0
  55. data/examples/io/tunnel.rb +6 -1
  56. data/examples/io/{xx-zip.rb → zip.rb} +0 -0
  57. data/examples/performance/fiber_transfer.rb +2 -1
  58. data/examples/performance/fs_read.rb +5 -6
  59. data/examples/{io/xx-switch.rb → performance/switch.rb} +2 -1
  60. data/examples/performance/thread-vs-fiber/{xx-httparty_multi.rb → httparty_multi.rb} +3 -4
  61. data/examples/performance/thread-vs-fiber/{xx-httparty_threaded.rb → httparty_threaded.rb} +0 -0
  62. data/examples/performance/thread-vs-fiber/polyphony_mt_server.rb +1 -1
  63. data/examples/performance/thread-vs-fiber/polyphony_server.rb +1 -1
  64. data/examples/performance/thread-vs-fiber/polyphony_server_read_loop.rb +1 -1
  65. data/examples/performance/thread-vs-fiber/threaded_server.rb +1 -5
  66. data/examples/performance/thread_pool_perf.rb +6 -7
  67. data/ext/polyphony/backend.h +40 -0
  68. data/ext/polyphony/event.c +3 -3
  69. data/ext/polyphony/extconf.rb +1 -1
  70. data/ext/polyphony/fiber.c +66 -6
  71. data/ext/polyphony/{libev_agent.c → libev_backend.c} +237 -238
  72. data/ext/polyphony/polyphony.c +3 -3
  73. data/ext/polyphony/polyphony.h +15 -20
  74. data/ext/polyphony/polyphony_ext.c +3 -4
  75. data/ext/polyphony/queue.c +5 -6
  76. data/ext/polyphony/ring_buffer.c +0 -1
  77. data/ext/polyphony/thread.c +36 -33
  78. data/lib/polyphony.rb +26 -39
  79. data/lib/polyphony/adapters/fs.rb +1 -1
  80. data/lib/polyphony/adapters/irb.rb +2 -17
  81. data/lib/polyphony/adapters/mysql2.rb +19 -0
  82. data/lib/polyphony/adapters/postgres.rb +5 -5
  83. data/lib/polyphony/adapters/process.rb +2 -5
  84. data/lib/polyphony/adapters/readline.rb +17 -0
  85. data/lib/polyphony/adapters/redis.rb +1 -1
  86. data/lib/polyphony/adapters/sequel.rb +45 -0
  87. data/lib/polyphony/core/exceptions.rb +11 -0
  88. data/lib/polyphony/core/global_api.rb +17 -12
  89. data/lib/polyphony/core/resource_pool.rb +20 -7
  90. data/lib/polyphony/core/sync.rb +46 -8
  91. data/lib/polyphony/core/throttler.rb +1 -1
  92. data/lib/polyphony/extensions/core.rb +30 -30
  93. data/lib/polyphony/extensions/fiber.rb +30 -49
  94. data/lib/polyphony/extensions/io.rb +60 -16
  95. data/lib/polyphony/extensions/openssl.rb +6 -6
  96. data/lib/polyphony/extensions/socket.rb +14 -15
  97. data/lib/polyphony/extensions/thread.rb +6 -5
  98. data/lib/polyphony/version.rb +1 -1
  99. data/polyphony.gemspec +7 -3
  100. data/test/helper.rb +1 -1
  101. data/test/{test_agent.rb → test_backend.rb} +22 -22
  102. data/test/test_fiber.rb +29 -12
  103. data/test/test_io.rb +59 -1
  104. data/test/test_kernel.rb +5 -0
  105. data/test/test_resource_pool.rb +29 -4
  106. data/test/test_signal.rb +16 -37
  107. data/test/test_socket.rb +17 -0
  108. data/test/test_sync.rb +52 -0
  109. metadata +127 -97
  110. data/.gitbook.yaml +0 -4
  111. data/examples/adapters/concurrent-ruby.rb +0 -9
  112. data/examples/core/04-handling-signals.rb +0 -19
  113. data/examples/core/xx-agent.rb +0 -102
  114. data/examples/core/xx-at_exit.rb +0 -29
  115. data/examples/core/xx-caller.rb +0 -12
  116. data/examples/core/xx-daemon.rb +0 -14
  117. data/examples/core/xx-deadlock.rb +0 -8
  118. data/examples/core/xx-deferring-an-operation.rb +0 -14
  119. data/examples/core/xx-exception-backtrace.rb +0 -40
  120. data/examples/core/xx-fork-cleanup.rb +0 -22
  121. data/examples/core/xx-fork-spin.rb +0 -42
  122. data/examples/core/xx-fork-terminate.rb +0 -27
  123. data/examples/core/xx-move_on.rb +0 -23
  124. data/examples/core/xx-queue-async.rb +0 -120
  125. data/examples/core/xx-readpartial.rb +0 -18
  126. data/examples/core/xx-signals.rb +0 -16
  127. data/examples/core/xx-sleep-forever.rb +0 -9
  128. data/examples/core/xx-sleeping.rb +0 -25
  129. data/examples/core/xx-snooze-starve.rb +0 -16
  130. data/examples/core/xx-spin-fork.rb +0 -49
  131. data/examples/core/xx-state-machine.rb +0 -51
  132. data/examples/core/xx-stop.rb +0 -20
  133. data/examples/core/xx-supervisors.rb +0 -21
  134. data/examples/core/xx-thread-selector-sleep.rb +0 -51
  135. data/examples/core/xx-thread-selector-snooze.rb +0 -46
  136. data/examples/core/xx-thread-snooze.rb +0 -34
  137. data/examples/core/xx-timer-gc.rb +0 -17
  138. data/examples/core/xx-trace.rb +0 -79
  139. data/examples/performance/xx-array.rb +0 -11
  140. data/examples/performance/xx-fiber-switch.rb +0 -9
  141. data/examples/performance/xx-snooze.rb +0 -15
  142. data/examples/xx-spin.rb +0 -32
  143. data/ext/polyphony/agent.h +0 -41
@@ -1,102 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'bundler/setup'
4
- require 'polyphony'
5
-
6
- Exception.__disable_sanitized_backtrace__ = true
7
-
8
- class Test
9
- def test_sleep
10
- puts "going to sleep"
11
- sleep 1
12
- puts "done sleeping"
13
- end
14
-
15
- def test_spin
16
- spin {
17
- 10.times {
18
- STDOUT << '.'
19
- sleep 0.1
20
- }
21
- }
22
-
23
- puts "going to sleep\n"
24
- sleep 1
25
- puts 'woke up'
26
- end
27
-
28
- def test_file
29
- f = File.open(__FILE__, 'r')
30
- puts Thread.current.agent.read(f, +'', 10000, true)
31
-
32
- Thread.current.agent.write(STDOUT, "Write something: ")
33
- str = +''
34
- Thread.current.agent.read(STDIN, str, 5, false)
35
- puts str
36
- end
37
-
38
- def test_fork
39
- pid = fork do
40
- Thread.current.agent.post_fork
41
- puts 'child going to sleep'
42
- sleep 1
43
- puts 'child done sleeping'
44
- exit(42)
45
- end
46
-
47
- puts "Waiting for pid #{pid}"
48
- result = Thread.current.agent.waitpid(pid)
49
- puts "Done waiting"
50
- p result
51
- end
52
-
53
- def test_async
54
- async = Polyphony::Event.new
55
-
56
- spin {
57
- puts "signaller starting"
58
- sleep 1
59
- puts "signal"
60
- async.signal(:foo)
61
- }
62
-
63
- puts "awaiting event"
64
- p async.await
65
- end
66
-
67
- def test_queue
68
- q = Gyro::Queue.new
69
- spin {
70
- 10.times {
71
- q << Time.now.to_f
72
- sleep 0.2
73
- }
74
- q << :STOP
75
- }
76
-
77
- loop do
78
- value = q.shift
79
- break if value == :STOP
80
-
81
- p value
82
- end
83
- end
84
-
85
- def test_thread
86
- t = Thread.new do
87
- puts "thread going to sleep"
88
- sleep 0.2
89
- puts "thread done sleeping"
90
- end
91
-
92
- t.await
93
- end
94
- end
95
-
96
- t = Test.new
97
-
98
- t.methods.select { |m| m =~ /^test_/ }.each do |m|
99
- puts '*' * 40
100
- puts m
101
- t.send(m)
102
- end
@@ -1,29 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'bundler/setup'
4
- require 'polyphony'
5
-
6
- Exception.__disable_sanitized_backtrace__ = true
7
-
8
- child_pid = Polyphony.fork do
9
- at_exit do
10
- puts "at_exit"
11
- f = spin { sleep 10 }
12
- trap('SIGINT') { f.stop }
13
- f.await
14
- end
15
-
16
- f1 = spin { sleep 100 }
17
-
18
- puts "pid: #{Process.pid}"
19
-
20
- pid = Process.pid
21
-
22
- f1.join
23
- end
24
-
25
- sleep 0.1
26
- Process.kill('INT', child_pid)
27
- sleep 0.1
28
- Process.kill('INT', child_pid)
29
- Process.wait(child_pid)
@@ -1,12 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'bundler/setup'
4
- require 'polyphony'
5
-
6
- spin {
7
- spin {
8
- spin {
9
- pp Fiber.current.caller
10
- }.await
11
- }.await
12
- }.await
@@ -1,14 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'bundler/setup'
4
- require 'polyphony'
5
-
6
- Exception.__disable_sanitized_backtrace__ = true
7
-
8
- puts "pid: #{Process.pid}"
9
-
10
- Process.daemon(true, true)
11
-
12
- Polyphony::ThreadPool.process do
13
- puts "Hello world from pid #{Process.pid}"
14
- end
@@ -1,8 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'bundler/setup'
4
- require 'polyphony'
5
-
6
- spin { sleep }
7
-
8
- sleep
@@ -1,14 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'bundler/setup'
4
- require 'polyphony'
5
-
6
- spin do
7
- puts 'two'
8
- spin { puts 'four' }
9
- puts 'three'
10
- end
11
-
12
- puts 'one'
13
-
14
- suspend
@@ -1,40 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'bundler/setup'
4
-
5
- class E < Exception
6
- def initialize(msg)
7
- super
8
- # set_backtrace(caller)
9
- end
10
-
11
- alias_method :orig_backtrace, :backtrace
12
- def backtrace
13
- b = orig_backtrace
14
- p [:backtrace, b, caller]
15
- b
16
- end
17
- end
18
-
19
- def e1
20
- e2
21
- end
22
-
23
- def e2
24
- E.new('foo')
25
- end
26
-
27
- def e3
28
- raise E, 'bar'
29
- end
30
-
31
- e = e1
32
- p e
33
- puts e.backtrace&.join("\n")
34
-
35
- begin
36
- e3
37
- rescue Exception => e
38
- p e
39
- puts e.backtrace.join("\n")
40
- end
@@ -1,22 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'bundler/setup'
4
- require 'polyphony'
5
-
6
- Exception.__disable_sanitized_backtrace__ = true
7
-
8
- t = Thread.new do
9
- async = Gyro::Async.new
10
- spin { async.await }
11
- sleep 100
12
- end
13
-
14
- sleep 0.5
15
-
16
- Polyphony.fork do
17
- puts "forked #{Process.pid}"
18
- sleep 1
19
- puts "done sleeping"
20
- end
21
-
22
- sleep 50
@@ -1,42 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'bundler/setup'
4
- require 'polyphony'
5
-
6
- Exception.__disable_sanitized_backtrace__ = true
7
-
8
- puts "Parent pid: #{Process.pid}"
9
-
10
- i, o = IO.pipe
11
-
12
- pid = Polyphony.fork do
13
- puts "Child pid: #{Process.pid}"
14
- i.close
15
- spin do
16
- spin do
17
- p :sleep
18
- sleep 1
19
- rescue ::Interrupt => e
20
- p 1
21
- # the signal should be raised only in the main fiber
22
- o.puts "1-interrupt"
23
- end.await
24
- rescue Polyphony::Terminate
25
- puts "terminate!"
26
- end.await
27
- rescue ::Interrupt => e
28
- p 2
29
- o.puts "3-interrupt"
30
- ensure
31
- p 3
32
- o.close
33
- end
34
- sleep 0.2
35
- o.close
36
- watcher = Gyro::Child.new(pid)
37
- Process.kill('INT', pid)
38
- watcher.await
39
- buffer = i.read
40
-
41
- puts '*' * 40
42
- p buffer
@@ -1,27 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'bundler/setup'
4
- require 'polyphony'
5
-
6
- Exception.__disable_sanitized_backtrace__ = true
7
-
8
- pid = Polyphony.fork do
9
- f = spin do
10
- p 1
11
- sleep 1
12
- p 2
13
- ensure
14
- p 2.5
15
- end
16
- p 3
17
- snooze
18
- p 4
19
- # f.stop
20
- # f.join
21
- # Fiber.current.terminate_all_children
22
- # Fiber.current.await_all_children
23
- p 5
24
- end
25
-
26
- puts "Child pid: #{pid}"
27
- Process.wait(pid)
@@ -1,23 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'bundler/setup'
4
- require 'polyphony'
5
- Exception.__disable_sanitized_backtrace__ = true
6
-
7
- puts 'going to sleep...'
8
- move_on_after(1) do
9
- sleep 60
10
- puts 'woke up'
11
- end
12
-
13
- puts 'going to sleep...'
14
- move_on_after(0.5) do
15
- t0 = Time.now
16
- sleep(60)
17
- ensure
18
- puts 'woke up'
19
- end
20
-
21
- puts 'going to sleep...'
22
- value = move_on_after(1, with_value: :bar) { sleep 60 }
23
- puts "got value #{value.inspect}"
@@ -1,120 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'bundler/setup'
4
- require 'polyphony'
5
-
6
- Thread.event_selector = ->(thread) { Gyro::Selector.new(thread) }
7
-
8
- def bm(sym, x)
9
- t0 = Time.now
10
- send(sym, x)
11
- elapsed = Time.now - t0
12
- STDOUT.orig_puts "#{sym} #{x / elapsed}"
13
- end
14
-
15
- def test_queue(x)
16
- queue = Queue.new
17
- async = Gyro::Async.new
18
- t1 = Thread.new do
19
- Thread.current.setup_fiber_scheduling
20
- counter = 0
21
- loop {
22
- async.await if queue.empty?
23
- v = queue.pop
24
- counter += 1
25
- break if counter == x
26
- }
27
- ensure
28
- Thread.current.stop_event_selector
29
- end
30
- t2 = Thread.new do
31
- Thread.current.setup_fiber_scheduling
32
- x.times { |i|
33
- queue.push i
34
- async.signal!
35
- }
36
- ensure
37
- Thread.current.stop_event_selector
38
- end
39
- t1.join
40
- t2.join
41
- end
42
-
43
- def test_array_mutex(x)
44
- queue = []
45
- mutex = Mutex.new
46
- async = Gyro::Async.new
47
- t1 = Thread.new {
48
- Thread.current.setup_fiber_scheduling
49
- counter = 0
50
- loop {
51
- async.await if mutex.synchronize { queue.empty? }
52
- v = mutex.synchronize { queue.shift }
53
- counter += 1
54
- break if counter == x
55
- }
56
- }
57
- t2 = Thread.new {
58
- Thread.current.setup_fiber_scheduling
59
- x.times { |i|
60
- mutex.synchronize { queue.push i }
61
- async.signal!
62
- }
63
- }
64
- t1.join
65
- t2.join
66
- end
67
-
68
- # class Gyro::Queue
69
- # def initialize
70
- # @wait_queue = []
71
- # @queue = []
72
- # end
73
-
74
- # def <<(value)
75
- # async = @wait_queue.pop
76
- # if async
77
- # async.signal! value
78
- # else
79
- # @queue.push value
80
- # end
81
- # end
82
-
83
- # def shift
84
- # if @queue.empty?
85
- # async = Gyro::Async.new
86
- # @wait_queue << async
87
- # async.await
88
- # else
89
- # @queue.shift
90
- # end
91
- # end
92
- # end
93
-
94
- def test_gyro_queue(x)
95
- queue = Gyro::Queue.new
96
- x.times { |i| queue << i }
97
- t1 = Thread.new do
98
- Thread.current.setup_fiber_scheduling
99
- x.times { queue.shift }
100
- ensure
101
- Thread.current.stop_event_selector
102
- end
103
- t2 = Thread.new do
104
- Thread.current.setup_fiber_scheduling
105
- x.times { |i| queue << i }
106
- ensure
107
- Thread.current.stop_event_selector
108
- end
109
- t1.join
110
- t2.join
111
- end
112
-
113
- Thread.current.setup_fiber_scheduling
114
- # bm(:test_array_mutex, 1000000)
115
- loop {
116
- STDOUT.orig_puts "*" * 40
117
- bm(:test_queue, 1000000)
118
- bm(:test_gyro_queue, 1000000)
119
- }
120
-