polyphony 0.19 → 0.20

Sign up to get free protection for your applications and to get access to all the features.
Files changed (186) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -1
  3. data/.rubocop.yml +87 -1
  4. data/CHANGELOG.md +35 -0
  5. data/Gemfile.lock +17 -6
  6. data/README.md +200 -139
  7. data/Rakefile +4 -4
  8. data/TODO.md +35 -7
  9. data/bin/poly +11 -0
  10. data/docs/getting-started/getting-started.md +1 -1
  11. data/docs/summary.md +3 -0
  12. data/docs/technical-overview/exception-handling.md +94 -0
  13. data/docs/technical-overview/fiber-scheduling.md +99 -0
  14. data/examples/core/cancel.rb +8 -4
  15. data/examples/core/channel_echo.rb +18 -17
  16. data/examples/core/defer.rb +12 -0
  17. data/examples/core/enumerator.rb +4 -4
  18. data/examples/core/fiber_error.rb +9 -0
  19. data/examples/core/fiber_error_with_backtrace.rb +73 -0
  20. data/examples/core/fork.rb +6 -6
  21. data/examples/core/genserver.rb +16 -8
  22. data/examples/core/lock.rb +3 -3
  23. data/examples/core/move_on.rb +4 -3
  24. data/examples/core/move_on_twice.rb +5 -5
  25. data/examples/core/move_on_with_ensure.rb +8 -11
  26. data/examples/core/move_on_with_value.rb +14 -0
  27. data/examples/core/{multiple_spawn.rb → multiple_spin.rb} +5 -5
  28. data/examples/core/nested_cancel.rb +5 -5
  29. data/examples/core/{nested_multiple_spawn.rb → nested_multiple_spin.rb} +6 -6
  30. data/examples/core/nested_spin.rb +17 -0
  31. data/examples/core/pingpong.rb +21 -0
  32. data/examples/core/pulse.rb +4 -5
  33. data/examples/core/resource.rb +6 -4
  34. data/examples/core/resource_cancel.rb +6 -9
  35. data/examples/core/resource_delegate.rb +3 -3
  36. data/examples/core/sleep.rb +3 -3
  37. data/examples/core/sleep_spin.rb +19 -0
  38. data/examples/core/snooze.rb +32 -0
  39. data/examples/core/spin.rb +14 -0
  40. data/examples/core/{spawn_cancel.rb → spin_cancel.rb} +6 -7
  41. data/examples/core/spin_error.rb +17 -0
  42. data/examples/core/spin_error_backtrace.rb +30 -0
  43. data/examples/core/spin_uncaught_error.rb +15 -0
  44. data/examples/core/supervisor.rb +8 -8
  45. data/examples/core/supervisor_with_cancel_scope.rb +7 -7
  46. data/examples/core/supervisor_with_error.rb +8 -8
  47. data/examples/core/supervisor_with_manual_move_on.rb +6 -7
  48. data/examples/core/suspend.rb +13 -0
  49. data/examples/core/thread.rb +1 -1
  50. data/examples/core/thread_cancel.rb +9 -11
  51. data/examples/core/thread_pool.rb +18 -14
  52. data/examples/core/throttle.rb +7 -7
  53. data/examples/core/timeout.rb +3 -3
  54. data/examples/fs/read.rb +7 -9
  55. data/examples/http/config.ru +7 -3
  56. data/examples/http/cuba.ru +22 -0
  57. data/examples/http/happy_eyeballs.rb +6 -4
  58. data/examples/http/http_client.rb +1 -1
  59. data/examples/http/http_get.rb +1 -1
  60. data/examples/http/http_parse_experiment.rb +21 -16
  61. data/examples/http/http_proxy.rb +28 -26
  62. data/examples/http/http_server.rb +10 -10
  63. data/examples/http/http_server_forked.rb +6 -5
  64. data/examples/http/http_server_throttled.rb +3 -3
  65. data/examples/http/http_ws_server.rb +11 -11
  66. data/examples/http/https_raw_client.rb +1 -1
  67. data/examples/http/https_server.rb +8 -8
  68. data/examples/http/https_wss_server.rb +13 -11
  69. data/examples/http/rack_server.rb +2 -2
  70. data/examples/http/rack_server_https.rb +4 -4
  71. data/examples/http/rack_server_https_forked.rb +5 -5
  72. data/examples/http/websocket_secure_server.rb +6 -6
  73. data/examples/http/websocket_server.rb +5 -5
  74. data/examples/interfaces/pg_client.rb +4 -4
  75. data/examples/interfaces/pg_pool.rb +13 -6
  76. data/examples/interfaces/pg_transaction.rb +5 -4
  77. data/examples/interfaces/redis_channels.rb +15 -11
  78. data/examples/interfaces/redis_client.rb +2 -2
  79. data/examples/interfaces/redis_pubsub.rb +2 -1
  80. data/examples/interfaces/redis_pubsub_perf.rb +13 -9
  81. data/examples/io/backticks.rb +11 -0
  82. data/examples/io/cat.rb +4 -5
  83. data/examples/io/echo_client.rb +9 -4
  84. data/examples/io/echo_client_from_stdin.rb +20 -0
  85. data/examples/io/echo_pipe.rb +7 -8
  86. data/examples/io/echo_server.rb +8 -6
  87. data/examples/io/echo_server_with_timeout.rb +13 -10
  88. data/examples/io/echo_stdin.rb +3 -3
  89. data/examples/io/httparty.rb +2 -2
  90. data/examples/io/httparty_multi.rb +8 -4
  91. data/examples/io/httparty_threaded.rb +6 -2
  92. data/examples/io/io_read.rb +2 -2
  93. data/examples/io/irb.rb +16 -4
  94. data/examples/io/net-http.rb +3 -3
  95. data/examples/io/open.rb +17 -0
  96. data/examples/io/system.rb +3 -3
  97. data/examples/io/tcpserver.rb +15 -0
  98. data/examples/io/tcpsocket.rb +6 -5
  99. data/examples/performance/multi_snooze.rb +29 -0
  100. data/examples/performance/{perf_snooze.rb → snooze.rb} +7 -5
  101. data/examples/performance/snooze_raw.rb +39 -0
  102. data/ext/gyro/async.c +165 -0
  103. data/ext/gyro/child.c +167 -0
  104. data/ext/{ev → gyro}/extconf.rb +4 -3
  105. data/ext/gyro/gyro.c +316 -0
  106. data/ext/{ev/ev.h → gyro/gyro.h} +12 -7
  107. data/ext/gyro/gyro_ext.c +23 -0
  108. data/ext/{ev → gyro}/io.c +65 -57
  109. data/ext/{ev → gyro}/libev.h +0 -0
  110. data/ext/gyro/signal.c +117 -0
  111. data/ext/{ev → gyro}/socket.c +61 -6
  112. data/ext/gyro/timer.c +199 -0
  113. data/ext/libev/Changes +35 -0
  114. data/ext/libev/README +2 -1
  115. data/ext/libev/ev.c +213 -151
  116. data/ext/libev/ev.h +95 -88
  117. data/ext/libev/ev_epoll.c +26 -15
  118. data/ext/libev/ev_kqueue.c +11 -5
  119. data/ext/libev/ev_linuxaio.c +642 -0
  120. data/ext/libev/ev_poll.c +13 -8
  121. data/ext/libev/ev_port.c +5 -2
  122. data/ext/libev/ev_vars.h +14 -3
  123. data/ext/libev/ev_wrap.h +16 -0
  124. data/lib/ev_ext.bundle +0 -0
  125. data/lib/polyphony.rb +46 -50
  126. data/lib/polyphony/auto_run.rb +12 -0
  127. data/lib/polyphony/core/cancel_scope.rb +11 -7
  128. data/lib/polyphony/core/channel.rb +16 -9
  129. data/lib/polyphony/core/coprocess.rb +101 -51
  130. data/lib/polyphony/core/exceptions.rb +14 -12
  131. data/lib/polyphony/core/resource_pool.rb +21 -8
  132. data/lib/polyphony/core/supervisor.rb +10 -5
  133. data/lib/polyphony/core/sync.rb +7 -6
  134. data/lib/polyphony/core/thread.rb +4 -4
  135. data/lib/polyphony/core/thread_pool.rb +4 -4
  136. data/lib/polyphony/core/throttler.rb +6 -4
  137. data/lib/polyphony/extensions/core.rb +253 -0
  138. data/lib/polyphony/extensions/io.rb +28 -16
  139. data/lib/polyphony/extensions/openssl.rb +2 -1
  140. data/lib/polyphony/extensions/socket.rb +47 -52
  141. data/lib/polyphony/http.rb +4 -3
  142. data/lib/polyphony/http/agent.rb +68 -57
  143. data/lib/polyphony/http/server.rb +5 -5
  144. data/lib/polyphony/http/server/http1.rb +268 -0
  145. data/lib/polyphony/http/server/http2.rb +62 -0
  146. data/lib/polyphony/http/server/http2_stream.rb +104 -0
  147. data/lib/polyphony/http/server/rack.rb +64 -0
  148. data/lib/polyphony/http/server/request.rb +119 -0
  149. data/lib/polyphony/net.rb +26 -15
  150. data/lib/polyphony/postgres.rb +17 -13
  151. data/lib/polyphony/redis.rb +16 -15
  152. data/lib/polyphony/version.rb +1 -1
  153. data/lib/polyphony/websocket.rb +11 -4
  154. data/polyphony.gemspec +13 -9
  155. data/test/eg.rb +27 -0
  156. data/test/helper.rb +25 -0
  157. data/test/run.rb +5 -0
  158. data/test/test_async.rb +33 -0
  159. data/test/test_coprocess.rb +239 -77
  160. data/test/test_core.rb +95 -61
  161. data/test/test_gyro.rb +148 -0
  162. data/test/test_http_server.rb +313 -0
  163. data/test/test_io.rb +79 -27
  164. data/test/test_kernel.rb +22 -12
  165. data/test/test_signal.rb +36 -0
  166. data/test/test_timer.rb +24 -0
  167. metadata +89 -33
  168. data/examples/core/nested_async.rb +0 -17
  169. data/examples/core/next_tick.rb +0 -12
  170. data/examples/core/sleep_spawn.rb +0 -19
  171. data/examples/core/spawn.rb +0 -14
  172. data/examples/core/spawn_error.rb +0 -28
  173. data/examples/performance/perf_multi_snooze.rb +0 -21
  174. data/ext/ev/async.c +0 -168
  175. data/ext/ev/child.c +0 -169
  176. data/ext/ev/ev_ext.c +0 -23
  177. data/ext/ev/ev_module.c +0 -242
  178. data/ext/ev/signal.c +0 -119
  179. data/ext/ev/timer.c +0 -197
  180. data/lib/polyphony/core/fiber_pool.rb +0 -98
  181. data/lib/polyphony/extensions/kernel.rb +0 -169
  182. data/lib/polyphony/http/http1_adapter.rb +0 -254
  183. data/lib/polyphony/http/http2_adapter.rb +0 -157
  184. data/lib/polyphony/http/rack.rb +0 -25
  185. data/lib/polyphony/http/request.rb +0 -66
  186. data/test/test_ev.rb +0 -110
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/setup'
4
+ require 'polyphony/auto_run'
5
+
6
+ COUNT = 10_000
7
+
8
+ class ::Fiber
9
+ attr_accessor :tag
10
+ end
11
+
12
+ COUNTS = Hash.new { |h, k| h[k] = 0 }
13
+
14
+ def t(tag)
15
+ Fiber.current.tag = tag.to_s
16
+ COUNT.times do
17
+ COUNTS[tag] += 1
18
+ snooze
19
+ end
20
+ puts "#{tag} done"
21
+ rescue StandardError => e
22
+ puts e
23
+ end
24
+
25
+ GC.disable
26
+ cp1 = spin { t(:a) }
27
+ cp2 = spin { t(:b) }
28
+
29
+ sleep 0.01 while cp1.alive? || cp2.alive?
30
+
31
+ puts 'counts:'
32
+ p COUNTS
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/setup'
4
+ require 'polyphony/auto_run'
5
+
6
+ def my_sleep(t)
7
+ puts 'going to sleep...'
8
+ sleep t
9
+ puts 'woke up'
10
+ end
11
+
12
+ spin do
13
+ spin { my_sleep(1) }.await
14
+ end
@@ -1,18 +1,17 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'bundler/setup'
4
- require 'polyphony'
4
+ require 'polyphony/auto_run'
5
5
 
6
6
  spin do
7
- puts "going to sleep..."
8
7
  cancel_after(1) do
9
- async {
8
+ spin do
9
+ puts 'going to sleep...'
10
10
  sleep(2)
11
- }.await
11
+ ensure
12
+ puts 'woke up'
13
+ end.await
12
14
  end
13
15
  rescue Polyphony::Cancel => e
14
16
  puts "got error: #{e}"
15
- ensure
16
- puts "woke up"
17
17
  end
18
-
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/setup'
4
+ require 'polyphony/auto_run'
5
+ require 'polyphony/extensions/backtrace'
6
+
7
+ def error(t)
8
+ raise "hello #{t}"
9
+ end
10
+
11
+ def spin_with_error
12
+ spin { error(2) }
13
+ end
14
+
15
+ spin_with_error
16
+
17
+ puts 'done coprocing'
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/setup'
4
+ require 'polyphony/auto_run'
5
+
6
+ def error(t)
7
+ raise "hello #{t}"
8
+ end
9
+
10
+ def deferred_error(t)
11
+ snooze
12
+ de2(t)
13
+ end
14
+
15
+ def de2(t)
16
+ snooze
17
+ error(t)
18
+ end
19
+
20
+ def spin_with_error
21
+ spin { error(4) }
22
+ end
23
+
24
+ spin do
25
+ spin do
26
+ spin do
27
+ deferred_error(3)
28
+ end.await
29
+ end.await
30
+ end.await
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/setup'
4
+ require 'polyphony/auto_run'
5
+ require 'polyphony/extensions/backtrace'
6
+
7
+ def foo
8
+ spin do
9
+ spin do
10
+ raise 'This is an error'
11
+ end
12
+ end
13
+ end
14
+
15
+ foo
@@ -1,9 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'bundler/setup'
4
- require 'polyphony'
4
+ require 'polyphony/auto_run'
5
5
 
6
- async def my_sleep(t)
6
+ def my_sleep(t)
7
7
  puts "#{t} start"
8
8
  sleep(t)
9
9
  puts "#{t} done"
@@ -11,11 +11,11 @@ end
11
11
 
12
12
  puts "#{Time.now} waiting..."
13
13
  supervise do |s|
14
- s.coproc my_sleep(1)
15
- s.coproc my_sleep(2)
16
- s.coproc my_sleep(3)
17
- s.spin {
18
- puts "fiber count: #{Polyphony::FiberPool.size}"
19
- }
14
+ s.spin { my_sleep(1) }
15
+ s.spin { my_sleep(2) }
16
+ s.spin { my_sleep(3) }
17
+ s.spin do
18
+ puts "fiber count: #{Polyphony::Coprocess.list.size}"
19
+ end
20
20
  end
21
21
  puts "#{Time.now} done waiting"
@@ -1,9 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'bundler/setup'
4
- require 'polyphony'
4
+ require 'polyphony/auto_run'
5
5
 
6
- async def my_sleep(t)
6
+ def my_sleep(t)
7
7
  puts "start: #{t}"
8
8
  r = sleep(t)
9
9
  puts "my_sleep result #{r.inspect}"
@@ -13,11 +13,11 @@ end
13
13
  puts "#{Time.now} going to sleep..."
14
14
  move_on_after(0.5) do
15
15
  supervise do |s|
16
- puts "supervise block"
17
- s.coproc my_sleep(1)
18
- s.coproc my_sleep(2)
19
- s.coproc my_sleep(3)
16
+ puts 'supervise block'
17
+ s.spin my_sleep(1)
18
+ s.spin my_sleep(2)
19
+ s.spin my_sleep(3)
20
20
  end
21
- puts "supervisor done"
21
+ puts 'supervisor done'
22
22
  end
23
23
  puts "#{Time.now} woke up"
@@ -1,22 +1,22 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'bundler/setup'
4
- require 'polyphony'
4
+ require 'polyphony/auto_run'
5
5
 
6
- async def my_sleep(t)
6
+ def my_sleep(t)
7
7
  sleep(t)
8
- raise "blah"
8
+ raise 'foo'
9
9
  end
10
10
 
11
11
  spin do
12
12
  puts "#{Time.now} going to sleep..."
13
13
  supervise do |s|
14
- s.coproc my_sleep(1)
15
- s.coproc my_sleep(2)
16
- s.coproc my_sleep(3)
14
+ s.spin { my_sleep(1) }
15
+ s.spin { my_sleep(2) }
16
+ s.spin { my_sleep(3) }
17
17
  end
18
- rescue => e
19
- puts "exception from supervisor: #{e}"
18
+ # rescue StandardError => e
19
+ # puts "exception from supervisor: #{e}"
20
20
  ensure
21
21
  puts "#{Time.now} woke up"
22
22
  end
@@ -1,9 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'bundler/setup'
4
- require 'polyphony'
4
+ require 'polyphony/auto_run'
5
5
 
6
- async def my_sleep(t)
6
+ def my_sleep(t)
7
7
  puts "start: #{t}"
8
8
  sleep(t)
9
9
  puts "done: #{t}"
@@ -11,14 +11,13 @@ end
11
11
 
12
12
  puts "#{Time.now} going to sleep..."
13
13
  result = supervise do |s|
14
- fiber = Fiber.current
15
14
  spin do
16
15
  sleep(0.5)
17
- puts "stopping supervisor..."
16
+ puts 'stopping supervisor...'
18
17
  s.stop!
19
18
  end
20
- s.coproc my_sleep(1)
21
- s.coproc my_sleep(2)
22
- s.coproc my_sleep(3)
19
+ s.spin { my_sleep(1) }
20
+ s.spin { my_sleep(2) }
21
+ s.spin { my_sleep(3) }
23
22
  end
24
23
  puts "#{Time.now} woke up with #{result.inspect}"
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/setup'
4
+ require 'polyphony/auto_run'
5
+
6
+ spin do
7
+ 1.times do
8
+ puts Time.now
9
+ sleep 1
10
+ end
11
+ end
12
+
13
+ suspend
@@ -4,7 +4,7 @@ require 'bundler/setup'
4
4
  require 'polyphony'
5
5
 
6
6
  def lengthy_op
7
- IO.read('../../docs/reality-ui.bmpr')
7
+ IO.orig_read(__FILE__)
8
8
  end
9
9
 
10
10
  X = 1000
@@ -1,27 +1,25 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'bundler/setup'
4
- require 'polyphony'
4
+ require 'polyphony/auto_run'
5
5
 
6
6
  @op_count = 0
7
7
 
8
8
  def lengthy_op
9
- @op_count += 1
10
- acc = 0
11
- count = 0
12
- 100.times { acc += IO.read('../../docs/reality-ui.bmpr').bytesize; count += 1; p count }
13
- acc / count
9
+ 100.times do
10
+ sleep 0.01
11
+ @op_count += 1
12
+ end
13
+ @op_count
14
14
  end
15
15
 
16
16
  spin do
17
- t0 = Time.now
18
- cancel_after(0.01) do
17
+ cancel_after(0.1) do
19
18
  data = Polyphony::Thread.spin { lengthy_op }.await
20
- puts "read #{data.bytesize} bytes (#{Time.now - t0}s)"
19
+ puts "slept #{data} times"
21
20
  end
22
21
  rescue Exception => e
23
22
  puts "error: #{e}"
24
23
  ensure
25
- p @op_count
24
+ puts "slept #{@op_count} times"
26
25
  end
27
-
@@ -1,16 +1,16 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'bundler/setup'
4
- require 'polyphony'
4
+ require 'polyphony/auto_run'
5
5
 
6
6
  def lengthy_op
7
- data = IO.read('../../docs/dev-journal.md')
7
+ data = IO.read(__FILE__)
8
8
  data.clear
9
9
  # Socket.getaddrinfo('debian.org', 80)
10
- #Digest::SHA256.digest(IO.read('doc/Promise.html'))
10
+ # Digest::SHA256.digest(IO.read('doc/Promise.html'))
11
11
  end
12
12
 
13
- X = 1000
13
+ X = 100
14
14
 
15
15
  def compare_performance
16
16
  t0 = Time.now
@@ -26,18 +26,20 @@ def compare_performance
26
26
  Polyphony::ThreadPool.process { lengthy_op }
27
27
  end
28
28
  async_perf = X / (Time.now - t0)
29
- puts "seq thread pool performance: %g (X %0.2f)" % [
30
- async_perf, async_perf / native_perf
31
- ]
29
+ puts format(
30
+ 'seq thread pool performance: %g (X %0.2f)',
31
+ async_perf,
32
+ async_perf / native_perf
33
+ )
32
34
  end
33
35
 
34
36
  acc = 0
35
37
  count = 0
36
- 10.times do |i|
38
+ 10.times do |_i|
37
39
  t0 = Time.now
38
40
  supervise do |s|
39
41
  X.times do
40
- s.coproc Polyphony::ThreadPool.process { lengthy_op }
42
+ s.spin { Polyphony::ThreadPool.process { lengthy_op } }
41
43
  end
42
44
  end
43
45
  thread_pool_perf = X / (Time.now - t0)
@@ -45,13 +47,15 @@ def compare_performance
45
47
  count += 1
46
48
  end
47
49
  avg_perf = acc / count
48
- puts "avg thread pool performance: %g (X %0.2f)" % [
49
- avg_perf, avg_perf / native_perf
50
- ]
51
- rescue Exception => e
50
+ puts format(
51
+ 'avg thread pool performance: %g (X %0.2f)',
52
+ avg_perf,
53
+ avg_perf / native_perf
54
+ )
55
+ rescue Exception => e
52
56
  p e
53
57
  puts e.backtrace.join("\n")
54
58
  end
55
59
  end
56
60
 
57
- spin { compare_performance }
61
+ spin { compare_performance }
@@ -1,16 +1,16 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'bundler/setup'
4
- require 'polyphony'
4
+ require 'polyphony/auto_run'
5
5
 
6
- spin {
6
+ spin do
7
7
  throttled_loop(3) { STDOUT << '.' }
8
- }
8
+ end
9
9
 
10
- spin {
10
+ spin do
11
11
  throttled_loop(rate: 2) { STDOUT << '?' }
12
- }
12
+ end
13
13
 
14
- spin {
14
+ spin do
15
15
  throttled_loop(interval: 1) { STDOUT << '*' }
16
- }
16
+ end
@@ -1,10 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'bundler/setup'
4
- require 'polyphony'
4
+ require 'polyphony/auto_run'
5
5
 
6
- puts "going to sleep..."
6
+ puts 'going to sleep...'
7
7
  Timeout.timeout(1) do
8
8
  sleep 60
9
9
  end
10
- puts "woke up"
10
+ puts 'woke up'
data/examples/fs/read.rb CHANGED
@@ -1,23 +1,21 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'bundler/setup'
4
- require 'polyphony'
4
+ require 'polyphony/auto_run'
5
5
  require 'polyphony/fs'
6
6
 
7
- PATH = File.expand_path('../../../../docs/dev-journal.md', __dir__)
8
-
9
7
  def raw_read_file(x)
10
8
  t0 = Time.now
11
- x.times { IO.orig_read(PATH) }
9
+ x.times { IO.orig_read(__FILE__) }
12
10
  puts "raw_read_file: #{Time.now - t0}"
13
11
  end
14
12
 
15
13
  def threaded_read_file(x, y)
16
14
  t0 = Time.now
17
15
  threads = []
18
- y.times {
16
+ y.times do
19
17
  threads << Thread.new { x.times { IO.orig_read(PATH) } }
20
- }
18
+ end
21
19
  threads.each(&:join)
22
20
  puts "threaded_read_file: #{Time.now - t0}"
23
21
  end
@@ -25,9 +23,9 @@ end
25
23
  def thread_pool_read_file(x, y)
26
24
  t0 = Time.now
27
25
  supervise do |s|
28
- y.times {
26
+ y.times do
29
27
  s.spin { x.times { IO.read(PATH) } }
30
- }
28
+ end
31
29
  end
32
30
  puts "thread_pool_read_file: #{Time.now - t0}"
33
31
  end
@@ -37,4 +35,4 @@ X = ARGV[1] ? ARGV[1].to_i : 100
37
35
 
38
36
  raw_read_file(X * Y)
39
37
  threaded_read_file(X, Y)
40
- thread_pool_read_file(X, Y)
38
+ thread_pool_read_file(X, Y)