Feature #18411
closedIntroduce `Fiber.blocking` for disabling scheduler.
Description
When implementing pure-ruby IO scheduler, we may need to invoke some Ruby IO operations without entering the scheduler.
def io_write(fiber, io, buffer, length)
offset = 0
while length > 0
# From offset until the end:
chunk = buffer.to_str(offset, length)
case result = io.write_nonblock(chunk, exception: false)
when :wait_readable
self.io_wait(fiber, io, IO::READABLE)
when :wait_writable
self.io_wait(fiber, io, IO::WRITABLE)
else
offset += result
length -= result
end
end
return offset
end
There are some cases where even in this code read_nonblock
can invoke fiber scheduler creating infinite recursion.
Therefore, I propose to introduce Fiber.blocking{...}
which has almost identical implementation to Fiber.new(blocking: true) {}.resume
.
In the above code, we change the line:
case result = io.write_nonblock(chunk, exception: false)
to
case result = Fiber.blocking{io.write_nonblock(chunk, exception: false)}
This ensures that write_nonblock
can never enter the scheduler again.
Updated by ioquatix (Samuel Williams) about 3 years ago
@matz (Yukihiro Matsumoto) this isn't strictly necessary but makes pure Ruby implementation of IO read/write hooks more efficient. I'm not sure if there is valid case for general user code. Can we consider it for Ruby 3.1?
Updated by ioquatix (Samuel Williams) about 3 years ago
- Description updated (diff)
Updated by jeremyevans0 (Jeremy Evans) almost 3 years ago
- Tracker changed from Bug to Feature
- Backport deleted (
2.6: UNKNOWN, 2.7: UNKNOWN, 3.0: UNKNOWN)
Updated by ko1 (Koichi Sasada) over 2 years ago
Let me confirm that why write_nonblock
calls a fiber scheduler?
Or does it solve if write_nonblock
doesn't call a fiber scheduler?
Updated by ioquatix (Samuel Williams) over 2 years ago
io_uring
handles non-blocking read and write system calls using the ring buffer. So even read_nonblock
and write_nonblock
system calls can go via the fiber scheduler. The system call itself is asynchronous even if the IO is non-blocking. I have not investigated the performance much since io_uring
has not been in a completely usable state yet. But recently it was much better, so I may begin this evaluation soon.
Updated by ioquatix (Samuel Williams) about 2 years ago
It was accepted.
Updated by ioquatix (Samuel Williams) about 2 years ago
- Status changed from Open to Closed
- Assignee set to ioquatix (Samuel Williams)
It was merged.