
Issue #20413 has been updated by ioquatix (Samuel Williams). After discussing it with Eregon on Slack, he withdrew his objection to this change. In general, this change: - Aligns `Fiber.new` with `rb_fiber_new` so that they both produce non-blocking fibers. - Doesn't affect existing code, as there is no obvious usage of `rb_fiber_new` by GitHub code search (small/zero blast radius). - Only impacts usage within the fiber scheduler, i.e. no effect outside of fiber scheduler beside the predicate value itself. - Even within the fiber scheduler, it is transparent to user code. ---------------------------------------- Bug #20413: Enumerator can block fiber scheduler. https://bugs.ruby-lang.org/issues/20413#change-107841 * Author: ioquatix (Samuel Williams) * Status: Closed * Assignee: ioquatix (Samuel Williams) * Backport: 3.0: UNKNOWN, 3.1: REQUIRED, 3.2: REQUIRED, 3.3: REQUIRED ---------------------------------------- Using `Enumerator` in the event loop can cause problems as the fiber created by `rb_fiber_new` is blocking by default. It should be non-blocking. ```ruby #!/usr/bin/env ruby require 'async' Async do Async do while true puts "Hello" sleep 1 end end enumerator = Enumerator.new do |yielder| while true yielder << "World" sleep 1 end end while true puts enumerator.next end end ``` Before this PR, the output is: ```
./test.rb Hello World World World World World World ...
After this PR, the output is:
./test.rb Hello World Hello World Hello World Hello World Hello World ...
The reason why this happens, is because the enumerator `sleep` never yields to the event loop.
See <https://github.com/ruby/ruby/pull/10481> for the fix.
--
https://bugs.ruby-lang.org/