polyphony 0.78 → 0.81

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 (48) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +19 -0
  3. data/Gemfile.lock +2 -1
  4. data/examples/core/pingpong.rb +7 -4
  5. data/examples/core/zlib_stream.rb +15 -0
  6. data/ext/polyphony/backend_common.c +16 -8
  7. data/ext/polyphony/backend_common.h +9 -3
  8. data/ext/polyphony/backend_io_uring.c +85 -31
  9. data/ext/polyphony/backend_libev.c +33 -17
  10. data/ext/polyphony/fiber.c +27 -27
  11. data/ext/polyphony/polyphony.c +9 -8
  12. data/ext/polyphony/polyphony.h +21 -7
  13. data/ext/polyphony/thread.c +6 -2
  14. data/lib/polyphony/adapters/fs.rb +4 -0
  15. data/lib/polyphony/adapters/process.rb +14 -1
  16. data/lib/polyphony/adapters/redis.rb +28 -0
  17. data/lib/polyphony/adapters/sequel.rb +19 -1
  18. data/lib/polyphony/core/debug.rb +201 -0
  19. data/lib/polyphony/core/exceptions.rb +21 -6
  20. data/lib/polyphony/core/global_api.rb +228 -73
  21. data/lib/polyphony/core/resource_pool.rb +65 -20
  22. data/lib/polyphony/core/sync.rb +57 -12
  23. data/lib/polyphony/core/thread_pool.rb +42 -5
  24. data/lib/polyphony/core/throttler.rb +21 -5
  25. data/lib/polyphony/core/timer.rb +125 -1
  26. data/lib/polyphony/extensions/exception.rb +36 -6
  27. data/lib/polyphony/extensions/fiber.rb +244 -61
  28. data/lib/polyphony/extensions/io.rb +4 -2
  29. data/lib/polyphony/extensions/kernel.rb +9 -4
  30. data/lib/polyphony/extensions/object.rb +8 -0
  31. data/lib/polyphony/extensions/openssl.rb +3 -1
  32. data/lib/polyphony/extensions/socket.rb +458 -39
  33. data/lib/polyphony/extensions/thread.rb +108 -43
  34. data/lib/polyphony/extensions/timeout.rb +12 -1
  35. data/lib/polyphony/extensions.rb +1 -0
  36. data/lib/polyphony/net.rb +66 -7
  37. data/lib/polyphony/version.rb +1 -1
  38. data/lib/polyphony.rb +0 -2
  39. data/test/test_backend.rb +6 -2
  40. data/test/test_global_api.rb +0 -23
  41. data/test/test_io.rb +7 -7
  42. data/test/test_resource_pool.rb +1 -1
  43. data/test/test_signal.rb +15 -15
  44. data/test/test_thread.rb +1 -1
  45. data/test/test_throttler.rb +0 -6
  46. data/test/test_trace.rb +189 -24
  47. metadata +9 -8
  48. 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,22 +300,29 @@ 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
309
+ Thread.backend.trace(:unblock, oob_fiber, nil, @caller)
253
310
  result = block.call
254
311
  rescue Exception => e
255
312
  Thread.current.schedule_and_wakeup(Thread.main.main_fiber, e)
256
313
  result = e
257
314
  ensure
258
- Thread.backend.trace(:fiber_terminate, Fiber.current, result)
315
+ Thread.backend.trace(:terminate, Fiber.current, result)
259
316
  suspend
260
317
  end
261
318
  prepare_oob_fiber(oob_fiber, block)
262
- Thread.backend.trace(:fiber_create, oob_fiber)
319
+ Thread.backend.trace(:spin, oob_fiber, caller)
263
320
  oob_fiber.schedule_with_priority(nil)
264
321
  end
265
322
 
323
+ private
324
+
325
+ # :no-doc:
266
326
  def prepare_oob_fiber(fiber, block)
267
327
  fiber.oob = true
268
328
  fiber.tag = :oob
@@ -272,21 +332,24 @@ module Polyphony
272
332
  end
273
333
  end
274
334
 
275
- # Methods for controlling child fibers
335
+ # Child fiber control methods
276
336
  module ChildFiberControl
337
+
338
+ # Returns the fiber's children.
339
+ #
340
+ # @return [Array<Fiber>] child fibers
277
341
  def children
278
342
  (@children ||= {}).keys
279
343
  end
280
344
 
281
- def add_child(child_fiber)
282
- (@children ||= {})[child_fiber] = true
283
- child_fiber.monitor(self) if @supervise_mode
284
- end
285
-
286
- def remove_child(child_fiber)
287
- @children.delete(child_fiber) if @children
288
- end
289
-
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
290
353
  def spin(tag = nil, orig_caller = Kernel.caller, &block)
291
354
  f = Fiber.new { |v| f.run(v) }
292
355
  f.prepare(tag, block, orig_caller, self)
@@ -295,24 +358,37 @@ module Polyphony
295
358
  f
296
359
  end
297
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
298
366
  def terminate_all_children(graceful = false)
299
- return unless @children
367
+ return self unless @children
300
368
 
301
369
  e = Polyphony::Terminate.new
302
370
  @children.each_key do |c|
303
371
  c.graceful_shutdown = true if graceful
304
372
  c.raise e
305
373
  end
374
+ self
306
375
  end
307
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
308
381
  def await_all_children
309
382
  return unless @children && !@children.empty?
310
383
 
311
384
  Fiber.await(*@children.keys.reject { |c| c.dead? })
312
385
  end
313
386
 
387
+ # Terminates and blocks until all child fibers have terminated.
388
+ #
389
+ # @return [Fiber] self
314
390
  def shutdown_all_children(graceful = false)
315
- return unless @children
391
+ return self unless @children
316
392
 
317
393
  @children.keys.each do |c|
318
394
  next if c.dead?
@@ -320,12 +396,22 @@ module Polyphony
320
396
  c.terminate(graceful)
321
397
  c.await
322
398
  end
399
+ self
323
400
  end
324
401
 
325
- def attach_all_children_to(fiber)
326
- @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
327
409
  end
328
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
329
415
  def detach
330
416
  @parent.remove_child(self)
331
417
  @parent = @thread.main_fiber
@@ -333,60 +419,102 @@ module Polyphony
333
419
  self
334
420
  end
335
421
 
336
- 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)
337
427
  @parent.remove_child(self)
338
- @parent = fiber
339
- fiber.add_child(self)
428
+ @parent = parent
429
+ parent.add_child(self)
430
+ self
340
431
  end
341
432
 
342
- 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)
343
438
  @parent.remove_child(self)
344
- @parent = fiber
345
- fiber.add_child(self)
346
- 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
347
461
  end
348
462
  end
349
463
 
350
464
  # Fiber life cycle methods
351
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]
352
474
  def prepare(tag, block, caller, parent)
353
475
  @thread = Thread.current
354
476
  @tag = tag
355
477
  @parent = parent
356
478
  @caller = caller
357
479
  @block = block
358
- Thread.backend.trace(:fiber_create, self)
480
+ Thread.backend.trace(:spin, self, Kernel.caller[1..-1])
359
481
  schedule
360
482
  end
361
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]
362
488
  def run(first_value)
363
- setup first_value
489
+ Kernel.raise first_value if first_value.is_a?(Exception)
490
+ @running = true
491
+
492
+ Thread.backend.trace(:unblock, self, first_value, @caller)
364
493
  result = @block.(first_value)
365
- finalize result
494
+ finalize(result)
366
495
  rescue Polyphony::Restart => e
367
496
  restart_self(e.value)
368
497
  rescue Polyphony::MoveOn, Polyphony::Terminate => e
369
- finalize e.value
498
+ finalize(e.value)
370
499
  rescue Exception => e
371
500
  e.source_fiber = self
372
- finalize e, true
373
- end
374
-
375
- def setup(first_value)
376
- Kernel.raise first_value if first_value.is_a?(Exception)
377
-
378
- @running = true
501
+ finalize(e, true)
379
502
  end
380
503
 
381
504
  # Performs setup for a "raw" Fiber created using Fiber.new. Note that this
382
505
  # fiber is an orphan fiber (has no parent), since we cannot control how the
383
506
  # fiber terminates after it has already been created. Calling #setup_raw
384
507
  # allows the fiber to be scheduled and to receive messages.
508
+ #
509
+ # @return [void]
385
510
  def setup_raw
386
511
  @thread = Thread.current
387
512
  @running = true
388
513
  end
389
514
 
515
+ # Sets up the fiber as the main fiber for the current thread.
516
+ #
517
+ # @return [void]
390
518
  def setup_main_fiber
391
519
  @main = true
392
520
  @tag = :main
@@ -395,14 +523,23 @@ module Polyphony
395
523
  @children&.clear
396
524
  end
397
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]
398
530
  def restart_self(first_value)
399
531
  @mailbox = nil
400
532
  run(first_value)
401
533
  end
402
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]
403
540
  def finalize(result, uncaught_exception = false)
404
541
  result, uncaught_exception = finalize_children(result, uncaught_exception)
405
- Thread.backend.trace(:fiber_terminate, self, result)
542
+ Thread.backend.trace(:terminate, self, result)
406
543
  @result = result
407
544
 
408
545
  inform_monitors(result, uncaught_exception)
@@ -417,6 +554,10 @@ module Polyphony
417
554
  # Shuts down all children of the current fiber. If any exception occurs while
418
555
  # the children are shut down, it is returned along with the uncaught_exception
419
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]
420
561
  def finalize_children(result, uncaught_exception)
421
562
  shutdown_all_children(graceful_shutdown?)
422
563
  [result, uncaught_exception]
@@ -424,6 +565,11 @@ module Polyphony
424
565
  [e, true]
425
566
  end
426
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]
427
573
  def inform_monitors(result, uncaught_exception)
428
574
  if @monitors
429
575
  msg = [self, result]
@@ -436,18 +582,35 @@ module Polyphony
436
582
  end
437
583
  end
438
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
439
590
  def monitor(fiber)
440
591
  (@monitors ||= {})[fiber] = true
592
+ self
441
593
  end
442
594
 
595
+ # Removes a monitor fiber.
596
+ #
597
+ # @param fiber [Fiber] monitoring fiber
598
+ # @return [Fiber] self
443
599
  def unmonitor(fiber)
444
600
  (@monitors ||= []).delete(fiber)
601
+ self
445
602
  end
446
603
 
604
+ # Returns the list of monitoring fibers.
605
+ #
606
+ # @return [Array<Fiber>] monitoring fibers
447
607
  def monitors
448
608
  @monitors&.keys || []
449
609
  end
450
610
 
611
+ # Returns true if the fiber is dead.
612
+ #
613
+ # @return [bool] is fiber dead
451
614
  def dead?
452
615
  state == :dead
453
616
  end
@@ -466,10 +629,16 @@ class ::Fiber
466
629
  attr_accessor :tag, :thread, :parent, :oob
467
630
  attr_reader :result
468
631
 
632
+ # Returns true if fiber is running.
633
+ #
634
+ # @return [bool] is fiber running
469
635
  def running?
470
636
  @running
471
637
  end
472
638
 
639
+ # Returns a string representation of the fiber for debugging.
640
+ #
641
+ # @return [String] string representation
473
642
  def inspect
474
643
  if @tag
475
644
  "#<Fiber #{tag}:#{object_id} #{location} (#{state})>"
@@ -479,6 +648,9 @@ class ::Fiber
479
648
  end
480
649
  alias_method :to_s, :inspect
481
650
 
651
+ # Returns the source location for the fiber based on its caller.
652
+ #
653
+ # @return [String] source location
482
654
  def location
483
655
  if @oob
484
656
  "#{@caller[0]} (oob)"
@@ -487,6 +659,9 @@ class ::Fiber
487
659
  end
488
660
  end
489
661
 
662
+ # Returns the fiber's caller.
663
+ #
664
+ # @return [Array<String>] caller
490
665
  def caller
491
666
  spin_caller = @caller || []
492
667
  if @parent
@@ -496,10 +671,18 @@ class ::Fiber
496
671
  end
497
672
  end
498
673
 
499
- def set_caller(o)
500
- @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
501
681
  end
502
682
 
683
+ # Returns true if the fiber is the main fiber for its thread.
684
+ #
685
+ # @return [bool] is main fiber
503
686
  def main?
504
687
  @main
505
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)