polyphony 0.71 → 0.74

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.
Files changed (80) hide show
  1. checksums.yaml +4 -4
  2. data/.github/FUNDING.yml +1 -0
  3. data/.github/workflows/test.yml +15 -11
  4. data/.github/workflows/test_io_uring.yml +32 -0
  5. data/.gitignore +3 -1
  6. data/CHANGELOG.md +33 -4
  7. data/Gemfile.lock +16 -13
  8. data/TODO.md +1 -1
  9. data/bin/pdbg +1 -1
  10. data/docs/_user-guide/all-about-timers.md +1 -1
  11. data/docs/api-reference/exception.md +5 -1
  12. data/docs/api-reference/fiber.md +2 -2
  13. data/docs/faq.md +1 -1
  14. data/docs/getting-started/overview.md +8 -8
  15. data/docs/getting-started/tutorial.md +3 -3
  16. data/docs/main-concepts/concurrency.md +1 -1
  17. data/docs/main-concepts/extending.md +3 -3
  18. data/docs/main-concepts/fiber-scheduling.md +1 -1
  19. data/examples/core/calc.rb +37 -0
  20. data/examples/core/calc_with_restart.rb +40 -0
  21. data/examples/core/calc_with_supervise.rb +37 -0
  22. data/examples/core/message_based_supervision.rb +1 -1
  23. data/examples/core/ring.rb +29 -0
  24. data/examples/io/rack_server.rb +1 -1
  25. data/examples/io/tunnel.rb +1 -1
  26. data/examples/performance/fiber_transfer.rb +1 -1
  27. data/examples/performance/line_splitting.rb +1 -1
  28. data/examples/performance/thread-vs-fiber/compare.rb +1 -1
  29. data/ext/polyphony/backend_common.c +88 -18
  30. data/ext/polyphony/backend_common.h +8 -1
  31. data/ext/polyphony/backend_io_uring.c +280 -164
  32. data/ext/polyphony/backend_io_uring_context.c +2 -1
  33. data/ext/polyphony/backend_io_uring_context.h +3 -2
  34. data/ext/polyphony/backend_libev.c +42 -38
  35. data/ext/polyphony/event.c +5 -2
  36. data/ext/polyphony/extconf.rb +25 -13
  37. data/ext/polyphony/polyphony.c +10 -1
  38. data/ext/polyphony/polyphony.h +7 -1
  39. data/ext/polyphony/queue.c +12 -7
  40. data/ext/polyphony/runqueue_ring_buffer.c +6 -3
  41. data/ext/polyphony/socket_extensions.c +5 -2
  42. data/ext/polyphony/thread.c +1 -1
  43. data/lib/polyphony/adapters/irb.rb +11 -1
  44. data/lib/polyphony/{extensions → core}/debug.rb +0 -0
  45. data/lib/polyphony/core/global_api.rb +3 -6
  46. data/lib/polyphony/core/timer.rb +2 -2
  47. data/lib/polyphony/debugger.rb +3 -3
  48. data/lib/polyphony/extensions/exception.rb +45 -0
  49. data/lib/polyphony/extensions/fiber.rb +87 -11
  50. data/lib/polyphony/extensions/io.rb +2 -2
  51. data/lib/polyphony/extensions/{core.rb → kernel.rb} +0 -73
  52. data/lib/polyphony/extensions/openssl.rb +20 -5
  53. data/lib/polyphony/extensions/process.rb +19 -0
  54. data/lib/polyphony/extensions/socket.rb +20 -9
  55. data/lib/polyphony/extensions/thread.rb +9 -3
  56. data/lib/polyphony/extensions/timeout.rb +10 -0
  57. data/lib/polyphony/extensions.rb +9 -0
  58. data/lib/polyphony/version.rb +1 -1
  59. data/lib/polyphony.rb +2 -4
  60. data/polyphony.gemspec +1 -1
  61. data/test/coverage.rb +2 -2
  62. data/test/test_backend.rb +15 -17
  63. data/test/test_event.rb +1 -1
  64. data/test/test_ext.rb +1 -1
  65. data/test/test_fiber.rb +31 -7
  66. data/test/test_global_api.rb +23 -14
  67. data/test/test_io.rb +5 -5
  68. data/test/test_kernel.rb +2 -2
  69. data/test/test_process_supervision.rb +1 -1
  70. data/test/test_queue.rb +6 -6
  71. data/test/test_signal.rb +20 -1
  72. data/test/test_socket.rb +45 -10
  73. data/test/test_supervise.rb +85 -0
  74. data/test/test_sync.rb +2 -2
  75. data/test/test_thread.rb +22 -2
  76. data/test/test_thread_pool.rb +2 -2
  77. data/test/test_throttler.rb +3 -3
  78. data/test/test_timer.rb +3 -3
  79. data/test/test_trace.rb +1 -1
  80. metadata +19 -9
@@ -1,25 +1,46 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'fiber'
4
-
5
3
  require_relative '../core/exceptions'
6
4
 
7
5
  module Polyphony
8
6
  # Fiber control API
9
7
  module FiberControl
8
+ # Returns the fiber's monitoring mailbox queue, used for receiving fiber
9
+ # monitoring messages.
10
+ #
11
+ # @return [Polyphony::Queue] Monitoring mailbox queue
10
12
  def monitor_mailbox
11
13
  @monitor_mailbox ||= Polyphony::Queue.new
12
14
  end
13
15
 
16
+ # call-seq:
17
+ # fiber.stop(value = nil) -> fiber
18
+ # Fiber.interrupt(value = nil) -> fiber
19
+ #
20
+ # Stops the fiber by raising a Polyphony::MoveOn exception. The given value
21
+ # will become the fiber's return value.
22
+ #
23
+ # @param value [any] Fiber's eventual return value
24
+ # @return [Fiber] fiber
14
25
  def interrupt(value = nil)
15
26
  return if @running == false
16
27
 
17
28
  schedule Polyphony::MoveOn.new(value)
29
+ self
18
30
  end
19
31
  alias_method :stop, :interrupt
20
32
 
33
+ # call-seq:
34
+ # fiber.reset(value = nil) -> fiber
35
+ # fiber.restart(value = nil) -> fiber
36
+ #
37
+ # Restarts the fiber, with the given value serving as the first value passed
38
+ # to the fiber's block.
39
+ #
40
+ # @param value [any] value passed to fiber block
41
+ # @return [Fiber] restarted fiber
21
42
  def restart(value = nil)
22
- raise "Can''t restart main fiber" if @main
43
+ raise "Can't restart main fiber" if @main
23
44
 
24
45
  if @running
25
46
  schedule Polyphony::Restart.new(value)
@@ -33,32 +54,58 @@ module Polyphony
33
54
  end
34
55
  alias_method :reset, :restart
35
56
 
57
+ # Stops a fiber by raising a Polyphony::Cancel exception.
58
+ #
59
+ # @return [Fiber] fiber
36
60
  def cancel
37
61
  return if @running == false
38
62
 
39
63
  schedule Polyphony::Cancel.new
64
+ self
40
65
  end
41
66
 
67
+ # Sets the graceful shutdown flag for the fiber.
68
+ #
69
+ # @param graceful [bool] Whether or not to perform a graceful shutdown
42
70
  def graceful_shutdown=(graceful)
43
71
  @graceful_shutdown = graceful
44
72
  end
45
73
 
74
+ # Returns the graceful shutdown flag for the fiber.
75
+ #
76
+ # @return [bool]
46
77
  def graceful_shutdown?
47
78
  @graceful_shutdown
48
79
  end
49
80
 
81
+ # Terminates the fiber, optionally setting the graceful shutdown flag.
82
+ #
83
+ # @param graceful [bool] Whether to perform a graceful shutdown
84
+ # @return [Fiber]
50
85
  def terminate(graceful = false)
51
86
  return if @running == false
52
87
 
53
88
  @graceful_shutdown = graceful
54
89
  schedule Polyphony::Terminate.new
55
- end
56
-
90
+ self
91
+ end
92
+
93
+ # call-seq:
94
+ # fiber.raise(message) -> fiber
95
+ # fiber.raise(exception_class) -> fiber
96
+ # fiber.raise(exception_class, exception_message) -> fiber
97
+ # fiber.raise(exception) -> fiber
98
+ #
99
+ # Raises an exception in the context of the fiber.
100
+ #
101
+ # @return [Fiber]
57
102
  def raise(*args)
58
103
  error = error_from_raise_args(args)
59
104
  schedule(error)
105
+ self
60
106
  end
61
107
 
108
+ # :no-doc:
62
109
  def error_from_raise_args(args)
63
110
  case (arg = args.shift)
64
111
  when String then RuntimeError.new(arg)
@@ -83,6 +130,8 @@ module Polyphony
83
130
  def supervise(*fibers, **opts, &block)
84
131
  block ||= supervise_opts_to_block(opts)
85
132
 
133
+ @supervise_mode = true
134
+ fibers = children if fibers.empty?
86
135
  fibers.each do |f|
87
136
  f.attach_to(self) unless f.parent == self
88
137
  f.monitor(self)
@@ -94,15 +143,18 @@ module Polyphony
94
143
  (fiber, result) = mailbox.shift
95
144
  block&.call(fiber, result)
96
145
  end
146
+ ensure
147
+ @supervise_mode = false
97
148
  end
98
149
 
99
150
  def supervise_opts_to_block(opts)
100
151
  block = opts[:on_done] || opts[:on_error]
101
- return nil unless block || opts[:restart]
152
+ restart = opts[:restart]
153
+ return nil unless block || restart
102
154
 
103
155
  error_only = !!opts[:on_error]
104
- restart_always = opts[:restart] == :always
105
- restart_on_error = opts[:restart] == :on_error
156
+ restart_always = (restart == :always) || (restart == true)
157
+ restart_on_error = restart == :on_error
106
158
 
107
159
  ->(f, r) do
108
160
  is_error = r.is_a?(Exception)
@@ -114,6 +166,17 @@ module Polyphony
114
166
 
115
167
  # Class methods for controlling fibers (namely await and select)
116
168
  module FiberControlClassMethods
169
+ # call-seq:
170
+ # Fiber.await(*fibers) -> [*results]
171
+ # Fiber.join(*fibers) -> [*results]
172
+ #
173
+ # Waits for all given fibers to terminate, then returns the respective
174
+ # return values for all terminated fibers. If any of the awaited fibers
175
+ # terminates with an uncaught exception, `Fiber.await` will await all the
176
+ # other fibers to terminate, then reraise the exception.
177
+ #
178
+ # @param *fibers [Array<Fiber>] fibers to wait for
179
+ # @return [Array<any>] return values of given fibers
117
180
  def await(*fibers)
118
181
  return [] if fibers.empty?
119
182
 
@@ -147,9 +210,15 @@ module Polyphony
147
210
  end
148
211
  alias_method :join, :await
149
212
 
213
+ # Waits for at least one of the given fibers to terminate, returning an
214
+ # array containing the first terminated fiber and its return value. If an
215
+ # exception occurs in one of the given fibers, it will be reraised.
216
+ #
217
+ # @param *fibers [Array<Fiber>] Fibers to wait for
218
+ # @return [Array] Array containing the first terminated fiber and its return value
150
219
  def select(*fibers)
151
220
  return nil if fibers.empty?
152
-
221
+
153
222
  current_fiber = self.current
154
223
  mailbox = current_fiber.monitor_mailbox
155
224
  fibers.each do |f|
@@ -163,7 +232,7 @@ module Polyphony
163
232
  while true
164
233
  (fiber, result) = mailbox.shift
165
234
  next unless fibers.include?(fiber)
166
-
235
+
167
236
  fibers.each { |f| f.unmonitor(current_fiber) }
168
237
  if result.is_a?(Exception)
169
238
  raise result
@@ -197,6 +266,7 @@ module Polyphony
197
266
 
198
267
  def add_child(child_fiber)
199
268
  (@children ||= {})[child_fiber] = true
269
+ child_fiber.monitor(self) if @supervise_mode
200
270
  end
201
271
 
202
272
  def remove_child(child_fiber)
@@ -207,6 +277,7 @@ module Polyphony
207
277
  f = Fiber.new { |v| f.run(v) }
208
278
  f.prepare(tag, block, orig_caller, self)
209
279
  (@children ||= {})[f] = true
280
+ f.monitor(self) if @supervise_mode
210
281
  f
211
282
  end
212
283
 
@@ -237,10 +308,15 @@ module Polyphony
237
308
  end
238
309
  end
239
310
 
311
+ def attach_all_children_to(fiber)
312
+ @children&.keys.each { |c| c.attach_to(fiber) }
313
+ end
314
+
240
315
  def detach
241
316
  @parent.remove_child(self)
242
317
  @parent = @thread.main_fiber
243
318
  @parent.add_child(self)
319
+ self
244
320
  end
245
321
 
246
322
  def attach_to(fiber)
@@ -328,7 +404,7 @@ module Polyphony
328
404
  # the children are shut down, it is returned along with the uncaught_exception
329
405
  # flag set. Otherwise, it returns the given arguments.
330
406
  def finalize_children(result, uncaught_exception)
331
- shutdown_all_children
407
+ shutdown_all_children(graceful_shutdown?)
332
408
  [result, uncaught_exception]
333
409
  rescue Exception => e
334
410
  [e, true]
@@ -103,7 +103,7 @@ class ::IO
103
103
  alias_method :orig_getc, :getc
104
104
  def getc
105
105
  return @read_buffer.slice!(0) if @read_buffer && !@read_buffer.empty?
106
-
106
+
107
107
  @read_buffer ||= +''
108
108
  Polyphony.backend_read(self, @read_buffer, 8192, false, -1)
109
109
  return @read_buffer.slice!(0) if !@read_buffer.empty?
@@ -116,7 +116,7 @@ class ::IO
116
116
  if buf
117
117
  return Polyphony.backend_read(self, buf, len, true, buf_pos)
118
118
  end
119
-
119
+
120
120
  @read_buffer ||= +''
121
121
  result = Polyphony.backend_read(self, @read_buffer, len, true, -1)
122
122
  return nil unless result
@@ -1,73 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'fiber'
4
- require 'timeout'
5
3
  require 'open3'
6
4
 
7
- require_relative '../core/exceptions'
8
-
9
- # Exeption overrides
10
- class ::Exception
11
- class << self
12
- attr_accessor :__disable_sanitized_backtrace__
13
- end
14
-
15
- attr_accessor :source_fiber, :raising_fiber
16
-
17
- alias_method :orig_initialize, :initialize
18
- def initialize(*args)
19
- @raising_fiber = Fiber.current
20
- orig_initialize(*args)
21
- end
22
-
23
- alias_method :orig_backtrace, :backtrace
24
- def backtrace
25
- unless @backtrace_called
26
- @backtrace_called = true
27
- return orig_backtrace
28
- end
29
-
30
- sanitized_backtrace
31
- end
32
-
33
- def sanitized_backtrace
34
- return sanitize(orig_backtrace) unless @raising_fiber
35
-
36
- backtrace = orig_backtrace || []
37
- sanitize(backtrace + @raising_fiber.caller)
38
- end
39
-
40
- POLYPHONY_DIR = File.expand_path(File.join(__dir__, '..'))
41
-
42
- def sanitize(backtrace)
43
- return backtrace if ::Exception.__disable_sanitized_backtrace__
44
-
45
- backtrace.reject { |l| l[POLYPHONY_DIR] }
46
- end
47
-
48
- def invoke
49
- Kernel.raise(self)
50
- end
51
- end
52
-
53
- # Overrides for Process
54
- module ::Process
55
- class << self
56
- alias_method :orig_detach, :detach
57
- def detach(pid)
58
- fiber = spin { Polyphony.backend_waitpid(pid) }
59
- fiber.define_singleton_method(:pid) { pid }
60
- fiber
61
- end
62
-
63
- alias_method :orig_daemon, :daemon
64
- def daemon(*args)
65
- orig_daemon(*args)
66
- Polyphony.original_pid = Process.pid
67
- end
68
- end
69
- end
70
-
71
5
  # Kernel extensions (methods available to all objects / call sites)
72
6
  module ::Kernel
73
7
  alias_method :orig_sleep, :sleep
@@ -159,10 +93,3 @@ module ::Kernel
159
93
  end
160
94
  end
161
95
  end
162
-
163
- # Override Timeout to use cancel scope
164
- module ::Timeout
165
- def self.timeout(sec, klass = Timeout::Error, message = 'execution expired', &block)
166
- cancel_after(sec, with_exception: [klass, message], &block)
167
- end
168
- end
@@ -130,24 +130,32 @@ class ::OpenSSL::SSL::SSLServer
130
130
  end
131
131
  end
132
132
 
133
+ # STDOUT.puts 'SSLServer#accept'
133
134
  sock, = @svr.accept
135
+ # STDOUT.puts "- raw sock: #{sock.inspect}"
134
136
  begin
135
137
  ssl = OpenSSL::SSL::SSLSocket.new(sock, @ctx)
138
+ # STDOUT.puts "- ssl sock: #{ssl.inspect}"
136
139
  ssl.sync_close = true
137
140
  if @use_accept_worker
141
+ # STDOUT.puts "- send to accept worker"
138
142
  @accept_worker_fiber << [ssl, Fiber.current]
139
- receive
143
+ # STDOUT.puts "- wait for accept worker"
144
+ r = receive
145
+ # STDOUT.puts "- got reply from accept worker: #{r.inspect}"
146
+ r.invoke if r.is_a?(Exception)
140
147
  else
141
148
  ssl.accept
142
149
  end
143
150
  ssl
144
- rescue Exception => ex
151
+ rescue Exception => e
152
+ # STDOUT.puts "- accept exception: #{e.inspect}"
145
153
  if ssl
146
154
  ssl.close
147
155
  else
148
156
  sock.close
149
157
  end
150
- raise ex
158
+ raise e
151
159
  end
152
160
  end
153
161
 
@@ -156,11 +164,18 @@ class ::OpenSSL::SSL::SSLServer
156
164
  @accept_worker_thread = Thread.new do
157
165
  fiber << Fiber.current
158
166
  loop do
167
+ # STDOUT.puts "- accept_worker wait for work"
159
168
  socket, peer = receive
169
+ # STDOUT.puts "- accept_worker got socket from peer #{peer.inspect}"
160
170
  socket.accept
171
+ # STDOUT.puts "- accept_worker accept returned"
161
172
  peer << socket
162
- rescue => e
163
- peer.schedule(e) if fiber
173
+ # STDOUT.puts "- accept_worker sent socket back to peer"
174
+ rescue Polyphony::BaseException
175
+ raise
176
+ rescue Exception => e
177
+ # STDOUT.puts "- accept_worker error: #{e}"
178
+ peer << e if peer
164
179
  end
165
180
  end
166
181
  @accept_worker_fiber = receive
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Overrides for Process
4
+ module ::Process
5
+ class << self
6
+ alias_method :orig_detach, :detach
7
+ def detach(pid)
8
+ fiber = spin { Polyphony.backend_waitpid(pid) }
9
+ fiber.define_singleton_method(:pid) { pid }
10
+ fiber
11
+ end
12
+
13
+ alias_method :orig_daemon, :daemon
14
+ def daemon(*args)
15
+ orig_daemon(*args)
16
+ Polyphony.original_pid = Process.pid
17
+ end
18
+ end
19
+ end
@@ -31,8 +31,8 @@ class ::Socket
31
31
  alias_method :orig_read, :read
32
32
  def read(maxlen = nil, buf = nil, buf_pos = 0)
33
33
  return Polyphony.backend_recv(self, buf, maxlen, buf_pos) if buf
34
- return Polyphony.backend_recv(self, buf || +'', maxlen, 0) if maxlen
35
-
34
+ return Polyphony.backend_recv(self, +'', maxlen, 0) if maxlen
35
+
36
36
  buf = +''
37
37
  len = buf.bytesize
38
38
  while true
@@ -120,8 +120,16 @@ class ::TCPSocket
120
120
 
121
121
  attr_reader :io
122
122
 
123
+ def self.open(*args)
124
+ new(*args)
125
+ end
126
+
127
+ def address_family(host)
128
+ host =~ /\:\:/ ? Socket::AF_INET6 : Socket::AF_INET
129
+ end
130
+
123
131
  def initialize(remote_host, remote_port, local_host = nil, local_port = nil)
124
- @io = Socket.new Socket::AF_INET, Socket::SOCK_STREAM
132
+ @io = Socket.new address_family(remote_host), Socket::SOCK_STREAM
125
133
  if local_host && local_port
126
134
  addr = Addrinfo.tcp(local_host, local_port)
127
135
  @io.bind(addr)
@@ -167,8 +175,8 @@ class ::TCPSocket
167
175
  alias_method :orig_read, :read
168
176
  def read(maxlen = nil, buf = nil, buf_pos = 0)
169
177
  return Polyphony.backend_recv(self, buf, maxlen, buf_pos) if buf
170
- return Polyphony.backend_recv(self, buf || +'', maxlen, 0) if maxlen
171
-
178
+ return Polyphony.backend_recv(self, +'', maxlen, 0) if maxlen
179
+
172
180
  buf = +''
173
181
  len = buf.bytesize
174
182
  while true
@@ -223,8 +231,12 @@ end
223
231
 
224
232
  # Override stock TCPServer code by encapsulating a Socket instance.
225
233
  class ::TCPServer
234
+ def address_family(host)
235
+ host =~ /\:\:/ ? Socket::AF_INET6 : Socket::AF_INET
236
+ end
237
+
226
238
  def initialize(hostname = nil, port = 0)
227
- @io = Socket.new Socket::AF_INET, Socket::SOCK_STREAM
239
+ @io = Socket.new address_family(hostname), Socket::SOCK_STREAM
228
240
  @io.bind(Addrinfo.tcp(hostname, port))
229
241
  @io.listen(0)
230
242
  end
@@ -232,7 +244,6 @@ class ::TCPServer
232
244
  alias_method :orig_accept, :accept
233
245
  def accept
234
246
  Polyphony.backend_accept(@io, TCPSocket)
235
- # @io.accept
236
247
  end
237
248
 
238
249
  def accept_loop(&block)
@@ -260,8 +271,8 @@ class ::UNIXSocket
260
271
  alias_method :orig_read, :read
261
272
  def read(maxlen = nil, buf = nil, buf_pos = 0)
262
273
  return Polyphony.backend_recv(self, buf, maxlen, buf_pos) if buf
263
- return Polyphony.backend_recv(self, buf || +'', maxlen, 0) if maxlen
264
-
274
+ return Polyphony.backend_recv(self, +'', maxlen, 0) if maxlen
275
+
265
276
  buf = +''
266
277
  len = buf.bytesize
267
278
  while true
@@ -18,14 +18,20 @@ class ::Thread
18
18
  def execute
19
19
  # backend must be created in the context of the new thread, therefore it
20
20
  # cannot be created in Thread#initialize
21
- @backend = Polyphony::Backend.new
21
+ raise_error = false
22
+ begin
23
+ @backend = Polyphony::Backend.new
24
+ rescue Exception => e
25
+ raise_error = true
26
+ raise e
27
+ end
22
28
  setup
23
29
  @ready = true
24
30
  result = @block.(*@args)
25
31
  rescue Polyphony::MoveOn, Polyphony::Terminate => e
26
32
  result = e.value
27
33
  rescue Exception => e
28
- result = e
34
+ raise_error ? (raise e) : (result = e)
29
35
  ensure
30
36
  @ready = true
31
37
  finalize(result)
@@ -48,7 +54,7 @@ class ::Thread
48
54
  @result = result
49
55
  signal_waiters(result)
50
56
  end
51
- @backend.finalize
57
+ @backend&.finalize
52
58
  end
53
59
 
54
60
  def signal_waiters(result)
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'timeout'
4
+
5
+ # Override Timeout to use cancel scope
6
+ module ::Timeout
7
+ def self.timeout(sec, klass = Timeout::Error, message = 'execution expired', &block)
8
+ cancel_after(sec, with_exception: [klass, message], &block)
9
+ end
10
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative './extensions/exception'
4
+ require_relative './extensions/fiber'
5
+ require_relative './extensions/io'
6
+ require_relative './extensions/kernel'
7
+ require_relative './extensions/process'
8
+ require_relative './extensions/thread'
9
+ require_relative './extensions/timeout'
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Polyphony
4
- VERSION = '0.71'
4
+ VERSION = '0.74'
5
5
  end
data/lib/polyphony.rb CHANGED
@@ -2,15 +2,13 @@
2
2
 
3
3
  require 'fiber'
4
4
  require_relative './polyphony_ext'
5
-
6
- require_relative './polyphony/extensions/core'
7
5
  require_relative './polyphony/extensions/thread'
8
- require_relative './polyphony/extensions/fiber'
9
- require_relative './polyphony/extensions/io'
10
6
 
11
7
  Thread.current.setup_fiber_scheduling
12
8
  Thread.current.backend = Polyphony::Backend.new
13
9
 
10
+ require_relative './polyphony/extensions'
11
+ require_relative './polyphony/core/exceptions'
14
12
  require_relative './polyphony/core/global_api'
15
13
  require_relative './polyphony/core/resource_pool'
16
14
  require_relative './polyphony/core/sync'
data/polyphony.gemspec CHANGED
@@ -27,7 +27,7 @@ Gem::Specification.new do |s|
27
27
  s.add_development_dependency 'simplecov', '0.17.1'
28
28
  s.add_development_dependency 'rubocop', '0.85.1'
29
29
  s.add_development_dependency 'pry', '0.13.1'
30
-
30
+
31
31
  s.add_development_dependency 'msgpack', '1.4.2'
32
32
  s.add_development_dependency 'httparty', '0.17.1'
33
33
  s.add_development_dependency 'localhost', '~>1.1.4'
data/test/coverage.rb CHANGED
@@ -24,10 +24,10 @@ module Coverage
24
24
  @result = {}
25
25
  trace = TracePoint.new(:line) do |tp|
26
26
  next if tp.path =~ /\(/
27
-
27
+
28
28
  absolute = File.expand_path(tp.path)
29
29
  next unless LIB_FILES.include?(absolute)# =~ /^#{LIB_DIR}/
30
-
30
+
31
31
  @result[absolute] ||= relevant_lines_for_filename(absolute)
32
32
  @result[absolute][tp.lineno - 1] = 1
33
33
  end