polyphony 0.43.11 → 0.45.4

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 (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
@@ -7,20 +7,6 @@ require_relative '../core/exceptions'
7
7
  module Polyphony
8
8
  # Fiber control API
9
9
  module FiberControl
10
- def await
11
- if @running == false
12
- return @result.is_a?(Exception) ? (Kernel.raise @result) : @result
13
- end
14
-
15
- fiber = Fiber.current
16
- @waiting_fibers ||= {}
17
- @waiting_fibers[fiber] = true
18
- suspend
19
- ensure
20
- @waiting_fibers&.delete(fiber)
21
- end
22
- alias_method :join, :await
23
-
24
10
  def interrupt(value = nil)
25
11
  return if @running == false
26
12
 
@@ -67,6 +53,10 @@ module Polyphony
67
53
  else RuntimeError.new
68
54
  end
69
55
  end
56
+
57
+ def interject(&block)
58
+ raise Polyphony::Interjection.new(block)
59
+ end
70
60
  end
71
61
 
72
62
  # Fiber supervision
@@ -113,7 +103,7 @@ module Polyphony
113
103
  suspend
114
104
  fibers.map(&:result)
115
105
  ensure
116
- await_select_cleanup(state)
106
+ await_select_cleanup(state) if state
117
107
  end
118
108
  alias_method :join, :await
119
109
 
@@ -175,21 +165,19 @@ module Polyphony
175
165
  state[:selected] = true
176
166
  end
177
167
  end
178
- end
179
-
180
- # Messaging functionality
181
- module FiberMessaging
182
- def <<(value)
183
- @mailbox << value
184
- end
185
- alias_method :send, :<<
186
-
187
- def receive
188
- @mailbox.shift
189
- end
190
168
 
191
- def receive_pending
192
- @mailbox.shift_all
169
+ # Creates and schedules with priority an out-of-band fiber that runs the
170
+ # supplied block. If any uncaught exception is raised while the fiber is
171
+ # running, it will bubble up to the main thread's main fiber, which will
172
+ # also be scheduled with priority. This method is mainly used trapping
173
+ # signals (see also the patched `Kernel#trap`)
174
+ def schedule_priority_oob_fiber(&block)
175
+ f = Fiber.new do
176
+ block.call
177
+ rescue Exception => e
178
+ Thread.current.break_out_of_ev_loop(Thread.main.main_fiber, e)
179
+ end
180
+ Thread.current.break_out_of_ev_loop(f, nil)
193
181
  end
194
182
  end
195
183
 
@@ -199,9 +187,9 @@ module Polyphony
199
187
  (@children ||= {}).keys
200
188
  end
201
189
 
202
- def spin(tag = nil, orig_caller = Kernel.caller, &block)
190
+ def spin(tag = nil, orig_caller = Kernel.caller, do_schedule: true, &block)
203
191
  f = Fiber.new { |v| f.run(v) }
204
- f.prepare(tag, block, orig_caller, self)
192
+ f.prepare(tag, block, orig_caller, self, do_schedule: do_schedule)
205
193
  (@children ||= {})[f] = true
206
194
  f
207
195
  end
@@ -221,14 +209,14 @@ module Polyphony
221
209
  def await_all_children
222
210
  return unless @children && !@children.empty?
223
211
 
224
- @results = @children.dup
212
+ results = @children.dup
225
213
  @on_child_done = proc do |c, r|
226
- @results[c] = r
227
- self.schedule if @children.empty?
214
+ results[c] = r
215
+ schedule if @children.empty?
228
216
  end
229
217
  suspend
230
218
  @on_child_done = nil
231
- @results.values
219
+ results.values
232
220
  end
233
221
 
234
222
  def shutdown_all_children
@@ -239,15 +227,14 @@ module Polyphony
239
227
 
240
228
  # Fiber life cycle methods
241
229
  module FiberLifeCycle
242
- def prepare(tag, block, caller, parent)
230
+ def prepare(tag, block, caller, parent, do_schedule: true)
243
231
  @thread = Thread.current
244
232
  @tag = tag
245
233
  @parent = parent
246
234
  @caller = caller
247
235
  @block = block
248
- @mailbox = Polyphony::Queue.new
249
236
  __fiber_trace__(:fiber_create, self)
250
- schedule
237
+ schedule if do_schedule
251
238
  end
252
239
 
253
240
  def run(first_value)
@@ -275,7 +262,6 @@ module Polyphony
275
262
  # allows the fiber to be scheduled and to receive messages.
276
263
  def setup_raw
277
264
  @thread = Thread.current
278
- @mailbox = Polyphony::Queue.new
279
265
  end
280
266
 
281
267
  def setup_main_fiber
@@ -284,11 +270,10 @@ module Polyphony
284
270
  @thread = Thread.current
285
271
  @running = true
286
272
  @children&.clear
287
- @mailbox = Polyphony::Queue.new
288
273
  end
289
274
 
290
275
  def restart_self(first_value)
291
- @mailbox = Polyphony::Queue.new
276
+ @mailbox = nil
292
277
  @when_done_procs = nil
293
278
  @waiting_fibers = nil
294
279
  run(first_value)
@@ -320,13 +305,10 @@ module Polyphony
320
305
  def inform_dependants(result, uncaught_exception)
321
306
  @parent&.child_done(self, result)
322
307
  @when_done_procs&.each { |p| p.(result) }
323
- @waiting_fibers&.each_key do |f|
324
- f.schedule(result)
325
- end
326
- return unless uncaught_exception && !@waiting_fibers
327
-
308
+ @waiting_fibers&.each_key { |f| f.schedule(result) }
309
+
328
310
  # propagate unaught exception to parent
329
- @parent&.schedule(result)
311
+ @parent&.schedule(result) if uncaught_exception && !@waiting_fibers
330
312
  end
331
313
 
332
314
  def when_done(&block)
@@ -340,14 +322,13 @@ end
340
322
  class ::Fiber
341
323
  prepend Polyphony::FiberControl
342
324
  include Polyphony::FiberSupervision
343
- include Polyphony::FiberMessaging
344
325
  include Polyphony::ChildFiberControl
345
326
  include Polyphony::FiberLifeCycle
346
327
 
347
328
  extend Polyphony::FiberControlClassMethods
348
329
 
349
330
  attr_accessor :tag, :thread, :parent
350
- attr_reader :result
331
+ attr_reader :result, :mailbox
351
332
 
352
333
  def running?
353
334
  @running
@@ -90,16 +90,27 @@ class ::IO
90
90
  # def each_codepoint
91
91
  # end
92
92
 
93
- # def getbyte
94
- # end
93
+ alias_method :orig_getbyte, :getbyte
94
+ def getbyte
95
+ char = getc
96
+ char ? char.getbyte(0) : nil
97
+ end
95
98
 
96
- # def getc
97
- # end
99
+ alias_method :orig_getc, :getc
100
+ def getc
101
+ return @read_buffer.slice!(0) if @read_buffer && !@read_buffer.empty?
102
+
103
+ @read_buffer ||= +''
104
+ Thread.current.backend.read(self, @read_buffer, 8192, false)
105
+ return @read_buffer.slice!(0) if !@read_buffer.empty?
106
+
107
+ nil
108
+ end
98
109
 
99
110
  alias_method :orig_read, :read
100
111
  def read(len = nil)
101
112
  @read_buffer ||= +''
102
- result = Thread.current.agent.read(self, @read_buffer, len, true)
113
+ result = Thread.current.backend.read(self, @read_buffer, len, true)
103
114
  return nil unless result
104
115
 
105
116
  already_read = @read_buffer
@@ -110,7 +121,7 @@ class ::IO
110
121
  alias_method :orig_readpartial, :read
111
122
  def readpartial(len, str = nil)
112
123
  @read_buffer ||= +''
113
- result = Thread.current.agent.read(self, @read_buffer, len, false)
124
+ result = Thread.current.backend.read(self, @read_buffer, len, false)
114
125
  raise EOFError unless result
115
126
 
116
127
  if str
@@ -124,12 +135,12 @@ class ::IO
124
135
 
125
136
  alias_method :orig_write, :write
126
137
  def write(str, *args)
127
- Thread.current.agent.write(self, str, *args)
138
+ Thread.current.backend.write(self, str, *args)
128
139
  end
129
140
 
130
141
  alias_method :orig_write_chevron, :<<
131
142
  def <<(str)
132
- Thread.current.agent.write(self, str)
143
+ Thread.current.backend.write(self, str)
133
144
  self
134
145
  end
135
146
 
@@ -163,20 +174,29 @@ class ::IO
163
174
  # def putc(obj)
164
175
  # end
165
176
 
177
+ LINEFEED = "\n"
178
+ LINEFEED_RE = /\n$/.freeze
179
+
166
180
  alias_method :orig_puts, :puts
167
181
  def puts(*args)
168
182
  if args.empty?
169
- write "\n"
183
+ write LINEFEED
170
184
  return
171
185
  end
172
186
 
173
- strs = args.inject([]) do |m, a|
174
- a = a.to_s
175
- m << a
176
- m << "\n" unless a =~ /\n$/
177
- m
187
+ idx = 0
188
+ while idx < args.size
189
+ arg = args[idx]
190
+ args[idx] = arg = arg.to_s unless arg.is_a?(String)
191
+ if arg =~ LINEFEED_RE
192
+ idx += 1
193
+ else
194
+ args.insert(idx + 1, LINEFEED)
195
+ idx += 2
196
+ end
178
197
  end
179
- write *strs
198
+
199
+ write(*args)
180
200
  nil
181
201
  end
182
202
 
@@ -203,7 +223,7 @@ class ::IO
203
223
  end
204
224
 
205
225
  def read_loop(&block)
206
- Thread.current.agent.read_loop(self, &block)
226
+ Thread.current.backend.read_loop(self, &block)
207
227
  end
208
228
 
209
229
  # alias_method :orig_read, :read
@@ -218,4 +238,28 @@ class ::IO
218
238
  # end
219
239
  # outbuf
220
240
  # end
241
+
242
+ def wait_readable(timeout = nil)
243
+ if timeout
244
+ move_on_after(timeout) do
245
+ Thread.current.backend.wait_io(self, false)
246
+ self
247
+ end
248
+ else
249
+ Thread.current.backend.wait_io(self, false)
250
+ self
251
+ end
252
+ end
253
+
254
+ def wait_writable(timeout = nil)
255
+ if timeout
256
+ move_on_after(timeout) do
257
+ Thread.current.backend.wait_io(self, true)
258
+ self
259
+ end
260
+ else
261
+ Thread.current.backend.wait_io(self, true)
262
+ self
263
+ end
264
+ end
221
265
  end
@@ -28,8 +28,8 @@ class ::OpenSSL::SSL::SSLSocket
28
28
  loop do
29
29
  result = accept_nonblock(exception: false)
30
30
  case result
31
- when :wait_readable then Thread.current.agent.wait_io(io, false)
32
- when :wait_writable then Thread.current.agent.wait_io(io, true)
31
+ when :wait_readable then Thread.current.backend.wait_io(io, false)
32
+ when :wait_writable then Thread.current.backend.wait_io(io, true)
33
33
  else
34
34
  return result
35
35
  end
@@ -40,8 +40,8 @@ class ::OpenSSL::SSL::SSLSocket
40
40
  def sysread(maxlen, buf = +'')
41
41
  loop do
42
42
  case (result = read_nonblock(maxlen, buf, exception: false))
43
- when :wait_readable then Thread.current.agent.wait_io(io, false)
44
- when :wait_writable then Thread.current.agent.wait_io(io, true)
43
+ when :wait_readable then Thread.current.backend.wait_io(io, false)
44
+ when :wait_writable then Thread.current.backend.wait_io(io, true)
45
45
  else return result
46
46
  end
47
47
  end
@@ -51,8 +51,8 @@ class ::OpenSSL::SSL::SSLSocket
51
51
  def syswrite(buf)
52
52
  loop do
53
53
  case (result = write_nonblock(buf, exception: false))
54
- when :wait_readable then Thread.current.agent.wait_io(io, false)
55
- when :wait_writable then Thread.current.agent.wait_io(io, true)
54
+ when :wait_readable then Thread.current.backend.wait_io(io, false)
55
+ when :wait_writable then Thread.current.backend.wait_io(io, true)
56
56
  else
57
57
  return result
58
58
  end
@@ -5,26 +5,17 @@ require 'socket'
5
5
  require_relative './io'
6
6
  require_relative '../core/thread_pool'
7
7
 
8
- class ::BasicSocket
9
- def write_nonblock(string, _options = {})
10
- write(string)
11
- end
12
-
13
- def read_nonblock(maxlen, str = nil, _options = {})
14
- readpartial(maxlen, str)
15
- end
16
- end
17
-
18
8
  # Socket overrides (eventually rewritten in C)
19
9
  class ::Socket
20
10
  def accept
21
- Thread.current.agent.accept(self)
11
+ Thread.current.backend.accept(self)
22
12
  end
23
13
 
24
14
  NO_EXCEPTION = { exception: false }.freeze
25
15
 
26
- def connect(remotesockaddr)
27
- Thread.current.agent.connect(self, remotesockaddr.ip_address, remotesockaddr.ip_port)
16
+ def connect(addr)
17
+ addr = Addrinfo.new(addr) if addr.is_a?(String)
18
+ Thread.current.backend.connect(self, addr.ip_address, addr.ip_port)
28
19
  end
29
20
 
30
21
  def recv(maxlen, flags = 0, outbuf = nil)
@@ -33,7 +24,7 @@ class ::Socket
33
24
  result = recv_nonblock(maxlen, flags, outbuf, **NO_EXCEPTION)
34
25
  case result
35
26
  when nil then raise IOError
36
- when :wait_readable then Thread.current.agent.wait_io(self, false)
27
+ when :wait_readable then Thread.current.backend.wait_io(self, false)
37
28
  else
38
29
  return result
39
30
  end
@@ -46,7 +37,7 @@ class ::Socket
46
37
  result = recvfrom_nonblock(maxlen, flags, @read_buffer, **NO_EXCEPTION)
47
38
  case result
48
39
  when nil then raise IOError
49
- when :wait_readable then Thread.current.agent.wait_io(self, false)
40
+ when :wait_readable then Thread.current.backend.wait_io(self, false)
50
41
  else
51
42
  return result
52
43
  end
@@ -128,6 +119,14 @@ class ::TCPSocket
128
119
  def reuse_port
129
120
  setsockopt(::Socket::SOL_SOCKET, ::Socket::SO_REUSEPORT, 1)
130
121
  end
122
+
123
+ def read_nonblock(len, str = nil, exception: true)
124
+ @io.read_nonblock(len, str, exception: exception)
125
+ end
126
+
127
+ def write_nonblock(buf, exception: true)
128
+ @io.write_nonblock(buf, exception: exception)
129
+ end
131
130
  end
132
131
 
133
132
  # Override stock TCPServer code by encapsulating a Socket instance.
@@ -16,21 +16,22 @@ class ::Thread
16
16
  end
17
17
 
18
18
  def execute
19
- # agent must be created in the context of the new thread, therefore it
19
+ # backend must be created in the context of the new thread, therefore it
20
20
  # cannot be created in Thread#initialize
21
- @agent = Polyphony::Agent.new
21
+ @backend = Polyphony::Backend.new
22
22
  setup
23
23
  @ready = true
24
24
  result = @block.(*@args)
25
25
  rescue Polyphony::MoveOn, Polyphony::Terminate => e
26
26
  result = e.value
27
- rescue Exception => result
27
+ rescue Exception => e
28
+ result = e
28
29
  ensure
29
30
  @ready = true
30
31
  finalize(result)
31
32
  end
32
33
 
33
- attr_accessor :agent
34
+ attr_accessor :backend
34
35
 
35
36
  def setup
36
37
  @main_fiber = Fiber.current
@@ -48,7 +49,7 @@ class ::Thread
48
49
  @result = result
49
50
  signal_waiters(result)
50
51
  end
51
- @agent.finalize
52
+ @backend.finalize
52
53
  end
53
54
 
54
55
  def signal_waiters(result)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Polyphony
4
- VERSION = '0.43.11'
4
+ VERSION = '0.45.4'
5
5
  end
@@ -21,17 +21,21 @@ Gem::Specification.new do |s|
21
21
  s.require_paths = ["lib"]
22
22
  s.required_ruby_version = '>= 2.6'
23
23
 
24
- s.add_development_dependency 'httparty', '0.17.0'
25
- s.add_development_dependency 'localhost', '1.1.4'
24
+ s.add_development_dependency 'rake-compiler', '1.1.1'
26
25
  s.add_development_dependency 'minitest', '5.13.0'
27
26
  s.add_development_dependency 'minitest-reporters', '1.4.2'
28
27
  s.add_development_dependency 'simplecov', '0.17.1'
29
28
  s.add_development_dependency 'rubocop', '0.85.1'
29
+ s.add_development_dependency 'pry', '0.13.1'
30
+
30
31
  s.add_development_dependency 'pg', '1.1.4'
31
- s.add_development_dependency 'rake-compiler', '1.0.5'
32
32
  s.add_development_dependency 'redis', '4.1.0'
33
33
  s.add_development_dependency 'hiredis', '0.6.3'
34
34
  s.add_development_dependency 'http_parser.rb', '~>0.6.0'
35
+ s.add_development_dependency 'rack', '>=2.0.8', '<2.3.0'
36
+ s.add_development_dependency 'mysql2', '0.5.3'
37
+ s.add_development_dependency 'sequel', '5.34.0'
38
+ s.add_development_dependency 'httparty', '0.17.1'
35
39
 
36
40
  s.add_development_dependency 'jekyll', '~>3.8.6'
37
41
  s.add_development_dependency 'jekyll-remote-theme', '~>0.4.1'