polyphony 0.79 → 0.81.1

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 (42) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +19 -0
  3. data/Gemfile.lock +2 -1
  4. data/examples/core/raw_buffer_test.rb +8 -0
  5. data/examples/core/zlib_stream.rb +16 -0
  6. data/ext/polyphony/backend_common.c +2 -1
  7. data/ext/polyphony/backend_common.h +7 -2
  8. data/ext/polyphony/backend_io_uring.c +69 -30
  9. data/ext/polyphony/polyphony.c +8 -0
  10. data/ext/polyphony/polyphony.h +11 -0
  11. data/lib/polyphony/adapters/fs.rb +4 -0
  12. data/lib/polyphony/adapters/process.rb +14 -1
  13. data/lib/polyphony/adapters/redis.rb +28 -0
  14. data/lib/polyphony/adapters/sequel.rb +19 -1
  15. data/lib/polyphony/core/debug.rb +129 -72
  16. data/lib/polyphony/core/exceptions.rb +21 -6
  17. data/lib/polyphony/core/global_api.rb +228 -73
  18. data/lib/polyphony/core/resource_pool.rb +65 -20
  19. data/lib/polyphony/core/sync.rb +57 -12
  20. data/lib/polyphony/core/thread_pool.rb +42 -5
  21. data/lib/polyphony/core/throttler.rb +21 -5
  22. data/lib/polyphony/core/timer.rb +125 -1
  23. data/lib/polyphony/extensions/exception.rb +36 -6
  24. data/lib/polyphony/extensions/fiber.rb +238 -57
  25. data/lib/polyphony/extensions/io.rb +4 -2
  26. data/lib/polyphony/extensions/kernel.rb +9 -4
  27. data/lib/polyphony/extensions/object.rb +8 -0
  28. data/lib/polyphony/extensions/openssl.rb +3 -1
  29. data/lib/polyphony/extensions/socket.rb +458 -39
  30. data/lib/polyphony/extensions/thread.rb +108 -43
  31. data/lib/polyphony/extensions/timeout.rb +12 -1
  32. data/lib/polyphony/extensions.rb +1 -0
  33. data/lib/polyphony/net.rb +66 -7
  34. data/lib/polyphony/version.rb +1 -1
  35. data/lib/polyphony.rb +0 -2
  36. data/test/test_backend.rb +6 -2
  37. data/test/test_global_api.rb +0 -23
  38. data/test/test_resource_pool.rb +1 -1
  39. data/test/test_throttler.rb +0 -6
  40. data/test/test_trace.rb +87 -0
  41. metadata +10 -8
  42. data/lib/polyphony/core/channel.rb +0 -15
@@ -3,12 +3,13 @@
3
3
  require_relative '../core/exceptions'
4
4
 
5
5
  module Polyphony
6
- # Fiber control API
6
+
7
+ # Fiber control methods
7
8
  module FiberControl
8
9
  # Returns the fiber's monitoring mailbox queue, used for receiving fiber
9
10
  # monitoring messages.
10
11
  #
11
- # @return [Polyphony::Queue] Monitoring mailbox queue
12
+ # @return [Polyphony::Queue] monitoring mailbox queue
12
13
  def monitor_mailbox
13
14
  @monitor_mailbox ||= Polyphony::Queue.new
14
15
  end
@@ -16,12 +17,13 @@ module Polyphony
16
17
  # call-seq:
17
18
  # fiber.stop(value = nil) -> fiber
18
19
  # Fiber.interrupt(value = nil) -> fiber
20
+ # Fiber.move_on(value = nil) -> fiber
19
21
  #
20
- # Stops the fiber by raising a Polyphony::MoveOn exception. The given value
21
- # will become the fiber's return value.
22
+ # Stops the fiber by raising a `Polyphony::MoveOn` exception. The given
23
+ # value will become the fiber's return value.
22
24
  #
23
- # @param value [any] Fiber's eventual return value
24
- # @return [Fiber] fiber
25
+ # @param value [any] fiber's eventual return value
26
+ # @return [Fiber] self
25
27
  def interrupt(value = nil)
26
28
  return if @running == false
27
29
 
@@ -29,6 +31,7 @@ module Polyphony
29
31
  self
30
32
  end
31
33
  alias_method :stop, :interrupt
34
+ alias_method :move_on, :interrupt
32
35
 
33
36
  # call-seq:
34
37
  # fiber.reset(value = nil) -> fiber
@@ -56,24 +59,27 @@ module Polyphony
56
59
 
57
60
  # Stops a fiber by raising a Polyphony::Cancel exception.
58
61
  #
59
- # @return [Fiber] fiber
60
- def cancel
62
+ # @param exception [Class, Exception] exception or exception class
63
+ # @return [Fiber] self
64
+ def cancel(exception = Polyphony::Cancel)
61
65
  return if @running == false
62
66
 
63
- schedule Polyphony::Cancel.new
67
+ value = (Class === exception) ? exception.new : exception
68
+ schedule value
64
69
  self
65
70
  end
66
71
 
67
72
  # Sets the graceful shutdown flag for the fiber.
68
73
  #
69
74
  # @param graceful [bool] Whether or not to perform a graceful shutdown
75
+ # @return [bool] graceful
70
76
  def graceful_shutdown=(graceful)
71
77
  @graceful_shutdown = graceful
72
78
  end
73
79
 
74
80
  # Returns the graceful shutdown flag for the fiber.
75
81
  #
76
- # @return [bool]
82
+ # @return [bool] true if graceful shutdown, otherwise false
77
83
  def graceful_shutdown?
78
84
  @graceful_shutdown
79
85
  end
@@ -81,7 +87,7 @@ module Polyphony
81
87
  # Terminates the fiber, optionally setting the graceful shutdown flag.
82
88
  #
83
89
  # @param graceful [bool] Whether to perform a graceful shutdown
84
- # @return [Fiber]
90
+ # @return [Fiber] self
85
91
  def terminate(graceful = false)
86
92
  return if @running == false
87
93
 
@@ -96,15 +102,36 @@ module Polyphony
96
102
  # fiber.raise(exception_class, exception_message) -> fiber
97
103
  # fiber.raise(exception) -> fiber
98
104
  #
99
- # Raises an exception in the context of the fiber.
105
+ # Raises an exception in the context of the fiber
100
106
  #
101
- # @return [Fiber]
107
+ # @return [Fiber] self
102
108
  def raise(*args)
103
109
  error = error_from_raise_args(args)
104
110
  schedule(error)
105
111
  self
106
112
  end
107
113
 
114
+ # Adds an interjection to the fiber. The current operation undertaken by the
115
+ # fiber will be interrupted, and the given block will be executed, and the
116
+ # operation will be resumed. This API is experimental and might be removed
117
+ # in the future.
118
+ #
119
+ # @param &block [Proc] given block
120
+ # @return [Fiber] self
121
+ def interject(&block)
122
+ raise Polyphony::Interjection.new(block)
123
+ end
124
+
125
+ # Blocks until the fiber has terminated, returning its return value.
126
+ #
127
+ # @return [any] fiber's return value
128
+ def await
129
+ Fiber.await(self).first
130
+ end
131
+ alias_method :join, :await
132
+
133
+ private
134
+
108
135
  # :no-doc:
109
136
  def error_from_raise_args(args)
110
137
  case (arg = args.shift)
@@ -114,19 +141,41 @@ module Polyphony
114
141
  else RuntimeError.new
115
142
  end
116
143
  end
117
-
118
- def interject(&block)
119
- raise Polyphony::Interjection.new(block)
120
- end
121
-
122
- def await
123
- Fiber.await(self).first
124
- end
125
- alias_method :join, :await
126
144
  end
127
145
 
128
- # Fiber supervision
146
+ # Fiber supervision methods
129
147
  module FiberSupervision
148
+
149
+ # call-seq:
150
+ # fiber.supervise
151
+ # fiber.supervise(fiber_a, fiber_b)
152
+ # fiber.supervise { |f, r| handle_terminated_fiber(f, r) }
153
+ # fiber.supervise(on_done: ->(f, r) { handle_terminated_fiber(f, r) })
154
+ # fiber.supervise(on_error: ->(f, e) { handle_error(f, e) })
155
+ # fiber.supervise(*fibers, restart: always)
156
+ # fiber.supervise(*fibers, restart: on_error)
157
+ #
158
+ # Supervises the given fibers or all child fibers. The fiber is put in
159
+ # supervision mode, which means any child added after calling `#supervise`
160
+ # will automatically be supervised. Depending on the given options, fibers
161
+ # may be automatically restarted.
162
+ #
163
+ # If a block is given, the block is called whenever a supervised fiber has
164
+ # terminated. If the `:on_done` option is given, that proc will be called
165
+ # when a supervised fiber has terminated. If the `:on_error` option is
166
+ # given, that proc will be called when a supervised fiber has terminated
167
+ # with an uncaught exception. If the `:restart` option equals `:always`,
168
+ # fibers will always be restarted. If the `:restart` option equals
169
+ # `:on_error`, fibers will be restarted only when terminated with an
170
+ # uncaught exception.
171
+ #
172
+ # This method blocks indefinitely.
173
+ #
174
+ # @param *fibers [Array<Fiber>] fibers to supervise
175
+ # @param on_done: [Proc, nil] proc to call when a supervised fiber is terminated
176
+ # @param on_error: [Proc, nil] proc to call when a supervised fiber is terminated with an exception
177
+ # @param restart: [:always, :on_error, nil] whether to restart terminated fibers
178
+ # @return [void]
130
179
  def supervise(*fibers, **opts, &block)
131
180
  block ||= supervise_opts_to_block(opts)
132
181
 
@@ -147,6 +196,9 @@ module Polyphony
147
196
  @supervise_mode = false
148
197
  end
149
198
 
199
+ private
200
+
201
+ # :no-doc:
150
202
  def supervise_opts_to_block(opts)
151
203
  block = opts[:on_done] || opts[:on_error]
152
204
  restart = opts[:restart]
@@ -164,8 +216,9 @@ module Polyphony
164
216
  end
165
217
  end
166
218
 
167
- # Class methods for controlling fibers (namely await and select)
219
+ # Fiber control class methods
168
220
  module FiberControlClassMethods
221
+
169
222
  # call-seq:
170
223
  # Fiber.await(*fibers) -> [*results]
171
224
  # Fiber.join(*fibers) -> [*results]
@@ -247,6 +300,9 @@ module Polyphony
247
300
  # running, it will bubble up to the main thread's main fiber, which will
248
301
  # also be scheduled with priority. This method is mainly used trapping
249
302
  # signals (see also the patched `Kernel#trap`)
303
+ #
304
+ # @param &block [Proc] given block
305
+ # @return [void]
250
306
  def schedule_priority_oob_fiber(&block)
251
307
  oob_fiber = Fiber.new do
252
308
  Fiber.current.setup_raw
@@ -264,6 +320,9 @@ module Polyphony
264
320
  oob_fiber.schedule_with_priority(nil)
265
321
  end
266
322
 
323
+ private
324
+
325
+ # :no-doc:
267
326
  def prepare_oob_fiber(fiber, block)
268
327
  fiber.oob = true
269
328
  fiber.tag = :oob
@@ -273,21 +332,24 @@ module Polyphony
273
332
  end
274
333
  end
275
334
 
276
- # Methods for controlling child fibers
335
+ # Child fiber control methods
277
336
  module ChildFiberControl
337
+
338
+ # Returns the fiber's children.
339
+ #
340
+ # @return [Array<Fiber>] child fibers
278
341
  def children
279
342
  (@children ||= {}).keys
280
343
  end
281
344
 
282
- def add_child(child_fiber)
283
- (@children ||= {})[child_fiber] = true
284
- child_fiber.monitor(self) if @supervise_mode
285
- end
286
-
287
- def remove_child(child_fiber)
288
- @children.delete(child_fiber) if @children
289
- end
290
-
345
+ # Creates a new child fiber.
346
+ #
347
+ # child = fiber.spin { sleep 10; fiber.stop }
348
+ #
349
+ # @param tag [any] child fiber's tag
350
+ # @param orig_caller [Array<String>] caller to set for fiber
351
+ # @param &block [Proc] child fiber's block
352
+ # @return [Fiber] child fiber
291
353
  def spin(tag = nil, orig_caller = Kernel.caller, &block)
292
354
  f = Fiber.new { |v| f.run(v) }
293
355
  f.prepare(tag, block, orig_caller, self)
@@ -296,24 +358,37 @@ module Polyphony
296
358
  f
297
359
  end
298
360
 
361
+ # Terminates all child fibers. This method will return before the fibers are
362
+ # actually terminated.
363
+ #
364
+ # @param graceful [bool] whether to perform a graceful termination
365
+ # @return [Fiber] self
299
366
  def terminate_all_children(graceful = false)
300
- return unless @children
367
+ return self unless @children
301
368
 
302
369
  e = Polyphony::Terminate.new
303
370
  @children.each_key do |c|
304
371
  c.graceful_shutdown = true if graceful
305
372
  c.raise e
306
373
  end
374
+ self
307
375
  end
308
376
 
377
+ # Block until all child fibers have terminated. Returns the return values
378
+ # for all child fibers.
379
+ #
380
+ # @return [Array<any>] return values of child fibers
309
381
  def await_all_children
310
382
  return unless @children && !@children.empty?
311
383
 
312
384
  Fiber.await(*@children.keys.reject { |c| c.dead? })
313
385
  end
314
386
 
387
+ # Terminates and blocks until all child fibers have terminated.
388
+ #
389
+ # @return [Fiber] self
315
390
  def shutdown_all_children(graceful = false)
316
- return unless @children
391
+ return self unless @children
317
392
 
318
393
  @children.keys.each do |c|
319
394
  next if c.dead?
@@ -321,12 +396,22 @@ module Polyphony
321
396
  c.terminate(graceful)
322
397
  c.await
323
398
  end
399
+ self
324
400
  end
325
401
 
326
- def attach_all_children_to(fiber)
327
- @children&.keys.each { |c| c.attach_to(fiber) }
402
+ # Attaches all child fibers to a new parent.
403
+ #
404
+ # @param parent [Fiber] new parent
405
+ # @return [Fiber] self
406
+ def attach_all_children_to(parent)
407
+ @children&.keys.each { |c| c.attach_to(parent) }
408
+ self
328
409
  end
329
410
 
411
+ # Detaches the fiber from its current parent. The fiber will be made a child
412
+ # of the main fiber (for the current thread.)
413
+ #
414
+ # @return [Fiber] self
330
415
  def detach
331
416
  @parent.remove_child(self)
332
417
  @parent = @thread.main_fiber
@@ -334,22 +419,58 @@ module Polyphony
334
419
  self
335
420
  end
336
421
 
337
- def attach_to(fiber)
422
+ # Attaches the fiber to a new parent.
423
+ #
424
+ # @param parent [Fiber] new parent
425
+ # @return [Fiber] self
426
+ def attach_to(parent)
338
427
  @parent.remove_child(self)
339
- @parent = fiber
340
- fiber.add_child(self)
428
+ @parent = parent
429
+ parent.add_child(self)
430
+ self
341
431
  end
342
432
 
343
- def attach_and_monitor(fiber)
433
+ # Attaches the fiber to the new parent and monitors the new parent.
434
+ #
435
+ # @param parent [Fiber] new parent
436
+ # @return [Fiber] self
437
+ def attach_and_monitor(parent)
344
438
  @parent.remove_child(self)
345
- @parent = fiber
346
- fiber.add_child(self)
347
- monitor(fiber)
439
+ @parent = parent
440
+ parent.add_child(self)
441
+ monitor(parent)
442
+ self
443
+ end
444
+
445
+ # Adds a child fiber reference. Used internally.
446
+ #
447
+ # @param child_fiber [Fiber] child fiber
448
+ # @return [Fiber] self
449
+ def add_child(child_fiber)
450
+ (@children ||= {})[child_fiber] = true
451
+ child_fiber.monitor(self) if @supervise_mode
452
+ self
453
+ end
454
+
455
+ # Removes a child fiber reference. Used internally.
456
+ #
457
+ # @param parent [Fiber] new parent
458
+ # @return [Fiber] self
459
+ def remove_child(child_fiber)
460
+ @children.delete(child_fiber) if @children
348
461
  end
349
462
  end
350
463
 
351
464
  # Fiber life cycle methods
352
465
  module FiberLifeCycle
466
+
467
+ # Prepares a fiber for running.
468
+ #
469
+ # @param tag [any] fiber's tag
470
+ # @param block [Proc] fiber's block
471
+ # @param caller [Array<String>] fiber's caller
472
+ # @param parent [Fiber] fiber's parent
473
+ # @return [void]
353
474
  def prepare(tag, block, caller, parent)
354
475
  @thread = Thread.current
355
476
  @tag = tag
@@ -360,35 +481,40 @@ module Polyphony
360
481
  schedule
361
482
  end
362
483
 
484
+ # Runs the fiber's block and handles uncaught exceptions.
485
+ #
486
+ # @param first_value [any] value passed to fiber on first resume
487
+ # @return [void]
363
488
  def run(first_value)
364
- setup first_value
489
+ Kernel.raise first_value if first_value.is_a?(Exception)
490
+ @running = true
491
+
365
492
  Thread.backend.trace(:unblock, self, first_value, @caller)
366
493
  result = @block.(first_value)
367
- finalize result
494
+ finalize(result)
368
495
  rescue Polyphony::Restart => e
369
496
  restart_self(e.value)
370
497
  rescue Polyphony::MoveOn, Polyphony::Terminate => e
371
- finalize e.value
498
+ finalize(e.value)
372
499
  rescue Exception => e
373
500
  e.source_fiber = self
374
- finalize e, true
375
- end
376
-
377
- def setup(first_value)
378
- Kernel.raise first_value if first_value.is_a?(Exception)
379
-
380
- @running = true
501
+ finalize(e, true)
381
502
  end
382
503
 
383
504
  # Performs setup for a "raw" Fiber created using Fiber.new. Note that this
384
505
  # fiber is an orphan fiber (has no parent), since we cannot control how the
385
506
  # fiber terminates after it has already been created. Calling #setup_raw
386
507
  # allows the fiber to be scheduled and to receive messages.
508
+ #
509
+ # @return [void]
387
510
  def setup_raw
388
511
  @thread = Thread.current
389
512
  @running = true
390
513
  end
391
514
 
515
+ # Sets up the fiber as the main fiber for the current thread.
516
+ #
517
+ # @return [void]
392
518
  def setup_main_fiber
393
519
  @main = true
394
520
  @tag = :main
@@ -397,11 +523,20 @@ module Polyphony
397
523
  @children&.clear
398
524
  end
399
525
 
526
+ # Resets the fiber's state and reruns the fiber.
527
+ #
528
+ # @param first_value [Fiber] first_value to pass to fiber after restarting
529
+ # @return [void]
400
530
  def restart_self(first_value)
401
531
  @mailbox = nil
402
532
  run(first_value)
403
533
  end
404
534
 
535
+ # Finalizes the fiber, handling its return value or any uncaught exception.
536
+ #
537
+ # @param result [any] return value
538
+ # @param uncaught_exception [Exception, nil] uncaught exception
539
+ # @return [void]
405
540
  def finalize(result, uncaught_exception = false)
406
541
  result, uncaught_exception = finalize_children(result, uncaught_exception)
407
542
  Thread.backend.trace(:terminate, self, result)
@@ -419,6 +554,10 @@ module Polyphony
419
554
  # Shuts down all children of the current fiber. If any exception occurs while
420
555
  # the children are shut down, it is returned along with the uncaught_exception
421
556
  # flag set. Otherwise, it returns the given arguments.
557
+ #
558
+ # @param result [any] fiber's return value
559
+ # @param uncaught_exception [Exception, nil] uncaught exception
560
+ # @return [void]
422
561
  def finalize_children(result, uncaught_exception)
423
562
  shutdown_all_children(graceful_shutdown?)
424
563
  [result, uncaught_exception]
@@ -426,6 +565,11 @@ module Polyphony
426
565
  [e, true]
427
566
  end
428
567
 
568
+ # Informs the fiber's monitors it is terminated.
569
+ #
570
+ # @param result [any] fiber's return value
571
+ # @param uncaught_exception [Exception, nil] uncaught exception
572
+ # @return [void]
429
573
  def inform_monitors(result, uncaught_exception)
430
574
  if @monitors
431
575
  msg = [self, result]
@@ -438,18 +582,35 @@ module Polyphony
438
582
  end
439
583
  end
440
584
 
585
+ # Adds a fiber to the list of monitoring fibers. Monitoring fibers will be
586
+ # notified on their monitor mailboxes when the fiber is terminated.
587
+ #
588
+ # @param fiber [Fiber] monitoring fiber
589
+ # @return [Fiber] self
441
590
  def monitor(fiber)
442
591
  (@monitors ||= {})[fiber] = true
592
+ self
443
593
  end
444
594
 
595
+ # Removes a monitor fiber.
596
+ #
597
+ # @param fiber [Fiber] monitoring fiber
598
+ # @return [Fiber] self
445
599
  def unmonitor(fiber)
446
600
  (@monitors ||= []).delete(fiber)
601
+ self
447
602
  end
448
603
 
604
+ # Returns the list of monitoring fibers.
605
+ #
606
+ # @return [Array<Fiber>] monitoring fibers
449
607
  def monitors
450
608
  @monitors&.keys || []
451
609
  end
452
610
 
611
+ # Returns true if the fiber is dead.
612
+ #
613
+ # @return [bool] is fiber dead
453
614
  def dead?
454
615
  state == :dead
455
616
  end
@@ -468,10 +629,16 @@ class ::Fiber
468
629
  attr_accessor :tag, :thread, :parent, :oob
469
630
  attr_reader :result
470
631
 
632
+ # Returns true if fiber is running.
633
+ #
634
+ # @return [bool] is fiber running
471
635
  def running?
472
636
  @running
473
637
  end
474
638
 
639
+ # Returns a string representation of the fiber for debugging.
640
+ #
641
+ # @return [String] string representation
475
642
  def inspect
476
643
  if @tag
477
644
  "#<Fiber #{tag}:#{object_id} #{location} (#{state})>"
@@ -481,6 +648,9 @@ class ::Fiber
481
648
  end
482
649
  alias_method :to_s, :inspect
483
650
 
651
+ # Returns the source location for the fiber based on its caller.
652
+ #
653
+ # @return [String] source location
484
654
  def location
485
655
  if @oob
486
656
  "#{@caller[0]} (oob)"
@@ -489,6 +659,9 @@ class ::Fiber
489
659
  end
490
660
  end
491
661
 
662
+ # Returns the fiber's caller.
663
+ #
664
+ # @return [Array<String>] caller
492
665
  def caller
493
666
  spin_caller = @caller || []
494
667
  if @parent
@@ -498,10 +671,18 @@ class ::Fiber
498
671
  end
499
672
  end
500
673
 
501
- def set_caller(o)
502
- @caller = o
674
+ # Sets the fiber's caller.
675
+ #
676
+ # @param caller [Array<String>] new caller
677
+ # @return [Fiber] self
678
+ def set_caller(caller)
679
+ @caller = caller
680
+ self
503
681
  end
504
682
 
683
+ # Returns true if the fiber is the main fiber for its thread.
684
+ #
685
+ # @return [bool] is main fiber
505
686
  def main?
506
687
  @main
507
688
  end
@@ -2,10 +2,12 @@
2
2
 
3
3
  require 'open3'
4
4
 
5
- # IO class method patches
5
+ # IO extensions
6
6
  class ::IO
7
7
  class << self
8
8
  alias_method :orig_binread, :binread
9
+
10
+ # TODO: add docs to all methods in this file
9
11
  def binread(name, length = nil, offset = nil)
10
12
  File.open(name, 'rb:ASCII-8BIT') do |f|
11
13
  f.seek(offset) if offset
@@ -76,7 +78,7 @@ end
76
78
 
77
79
  # IO instance method patches
78
80
  class ::IO
79
- def __parser_read_method__
81
+ def __read_method__
80
82
  :backend_read
81
83
  end
82
84
 
@@ -7,6 +7,8 @@ module ::Kernel
7
7
  alias_method :orig_sleep, :sleep
8
8
 
9
9
  alias_method :orig_backtick, :`
10
+
11
+ # TODO: add docs to all methods in this file
10
12
  def `(cmd)
11
13
  Open3.popen3(cmd) do |i, o, e, _t|
12
14
  i.close
@@ -72,10 +74,6 @@ module ::Kernel
72
74
  end
73
75
  end
74
76
 
75
- def pipe_to_eof(src, dest)
76
- src.read_loop { |data| dest << data }
77
- end
78
-
79
77
  alias_method :orig_trap, :trap
80
78
  def trap(sig, command = nil, &block)
81
79
  return orig_trap(sig, command) if command.is_a? String
@@ -92,4 +90,11 @@ module ::Kernel
92
90
  Fiber.schedule_priority_oob_fiber(&block)
93
91
  end
94
92
  end
93
+
94
+ private
95
+
96
+ # :no-doc:
97
+ def pipe_to_eof(src, dest)
98
+ src.read_loop { |data| dest << data }
99
+ end
95
100
  end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../core/global_api'
4
+
5
+ # Object extensions (methods available to all objects / call sites)
6
+ class ::Object
7
+ include Polyphony::GlobalAPI
8
+ end
@@ -5,11 +5,13 @@ require_relative './socket'
5
5
 
6
6
  # OpenSSL socket helper methods (to make it compatible with Socket API) and overrides
7
7
  class ::OpenSSL::SSL::SSLSocket
8
- def __parser_read_method__
8
+ def __read_method__
9
9
  :readpartial
10
10
  end
11
11
 
12
12
  alias_method :orig_initialize, :initialize
13
+
14
+ # TODO: add docs to all methods in this file
13
15
  def initialize(socket, context = nil)
14
16
  socket = socket.respond_to?(:io) ? socket.io || socket : socket
15
17
  context ? orig_initialize(socket, context) : orig_initialize(socket)