Feature #20102
Updated by ioquatix (Samuel Williams) 11 months ago
There are some tricky edge cases when using `Fibre#raise` and `Fiber#kill`, e.g. ```ruby fiber = nil killer = Fiber.new do fiber.raise("Stop") end fiber = Fiber.new do killer.resume end fiber.resume # 4:in `raise': attempt to raise a resuming fiber (FiberError) # 4:in `block in <main>' ``` Async has to deal with this edge case explicitly by rescuing the exception: https://github.com/socketry/async/blob/ffd019d9c1d547926a28fe8f36bf7bfe91d8a168/lib/async/task.rb#L226-L233 I'd like to avoid doing that and instead just ask "Can I kill/raise on this fiber right now?" which is determined by whether the fiber itself can be resumed or transferred to. To address this, I'd like to introduce `Fiber#resuming?`: ```c /* * call-seq: fiber.resumed? -> true or false * * Whether the fiber is currently resumed. */ VALUE rb_fiber_resuming_p(VALUE fiber_value) { struct rb_fiber_struct *fiber = fiber_ptr(fiber_value); if (FIBER_TERMINATED_P(fiber)) return RUBY_Qfalse; return RBOOL(fiber->resuming_fiber); } ``` See the PR: https://github.com/ruby/ruby/pull/9382