Module: FiberScheduler::Compatibility
- Defined in:
- lib/fiber_scheduler/compatibility.rb
Constant Summary collapse
- Close =
Class.new(RuntimeError)
Class Method Summary collapse
Instance Method Summary collapse
- #_volatile ⇒ Object
-
#close ⇒ Object
#close and #_volatile handle a complexity in Async::Scheduler#close, more specifically this line: github.com/socketry/async/blob/456df488d801572821eaf5ec2fda10e3b9744a5f/lib/async/scheduler.rb#L55.
- #fiber(*args, **opts, &block) ⇒ Object
Class Method Details
.internal? ⇒ Boolean
92 93 94 |
# File 'lib/fiber_scheduler/compatibility.rb', line 92 def self.internal? Thread.current[:_fiber_scheduler] end |
.set_internal! ⇒ Object
[View source]
88 89 90 |
# File 'lib/fiber_scheduler/compatibility.rb', line 88 def self.set_internal! Thread.current[:_fiber_scheduler] = true # Sets a FIBER local var! end |
Instance Method Details
#_volatile ⇒ Object
[View source]
84 85 86 |
# File 'lib/fiber_scheduler/compatibility.rb', line 84 def _volatile @_volatile ||= {} end |
#close ⇒ Object
#close and #_volatile handle a complexity in Async::Scheduler#close, more specifically this line: github.com/socketry/async/blob/456df488d801572821eaf5ec2fda10e3b9744a5f/lib/async/scheduler.rb#L55
69 70 71 72 73 74 75 76 77 78 79 80 81 82 |
# File 'lib/fiber_scheduler/compatibility.rb', line 69 def close super rescue if _volatile.empty? Kernel.raise else # #dup is used because #_volatile is modified during iteration. _volatile.dup.each do |fiber, _| fiber.raise(Close) end super # retry end end |
#fiber(*args, **opts, &block) ⇒ Object
[View source]
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
# File 'lib/fiber_scheduler/compatibility.rb', line 5 def fiber(*args, **opts, &block) return super unless Compatibility.internal? # This is `Fiber.schedule` call inside `FiberScheduler { ... }` block. type = args.first case type when :blocking Fiber.new(blocking: true) { Compatibility.set_internal! yield }.tap(&:resume) when :waiting parent = Fiber.current finished = false # prevents races blocking = false # prevents #unblock-ing a fiber that never blocked # Don't pass *args and **opts to an unknown fiber scheduler class. fiber = super() do Compatibility.set_internal! yield ensure finished = true unblock(nil, parent) if blocking end unless finished blocking = true block(nil, nil) end fiber when :volatile # Transfer to current fiber some time after a volatile fiber yields. unblock(nil, Fiber.current) # Alternative to #unblock: Fiber.scheduler.push(Fiber.current) fiber = Fiber.new(blocking: false) do Compatibility.set_internal! yield rescue Close # Fiber scheduler is closing. ensure _volatile.delete(Fiber.current) end _volatile[fiber] = nil fiber.tap(&:transfer) when nil # Don't pass *args and **opts to an unknown fiber scheduler class. super() do Compatibility.set_internal! yield end else raise "Unknown type" end end |