Noteflakes iconnoteflakes

OSS Friday Update - The Shape of Ruby I/O to Come

05·12·2025

I’m currently doing grant work for the Japanese Ruby Association on UringMachine, a new Ruby gem that provides a low-level API for working with io_uring. As part of my work I’ll be providing weekly updates on this website. Here’s what I did this week:

Why is The Fiber Scheduler Important?

I think there is some misunderstanding around the Ruby fiber scheduler interface. This is the only Ruby API that does not have a built-in implementation in Ruby itself, but rather requires an external library or gem. The question has been raised lately on Reddit, why doesn’t Ruby include an “official” implementation of the fiber scheduler?

I guess Samuel is really the person to ask this, but personally I would say this is really about experimentation, and seeing how far we can take the idea of a pluggable I/O implementation. Also, the open-ended design of this interface means that we can use a low-level API such as UringMachine to implement it.

What’s Coming Next Week?

Now that the fiber scheduler is feature complete, I’m looking to make it as robust as possible. For this, I intend to add a lot of tests. Right now, the fiber scheduler has 25 tests with 77 assertions, in about 560LOC (the fiber scheduler itself is at around 220LOC). To me this is not enough, so next week I’m going to add tests for the following:

In conjunction with all those tests, I’ll also start working on benchmarks for measuring the performance of the UringMachine low-level API against the UringMachine fiber scheduler and against the “normal” thread-based Ruby APIs.

In addition, I’m working on a pull request for adding an #io_close hook to the fiber scheduler interface in Ruby. Samuel already did some preparation for this, so I hope I can finish this in time for it to be merged in time for the release of Ruby 4.0.

I intend to release UringMachine 1.0 on Christmas, to mark the release of Ruby 4.0.

What About Papercraft?

This week I also managed to take the time to reflect on what I want to do next in Papercraft. I already wrote here about wanting to implement template inlining for Papercraft. I also wanted to rework how the compiled code is generated. I imagined a kind of DSL for code generation, but I didn’t really know what such a DSL would look like.

Then, a few days ago, the idea hit me. I’ve already played with this idea a last year, when I wrote Sirop, a sister gem to Papercraft that does a big part of the work of converting code into AST’s and vice versa. Here’s what I put in the readme:

Future directions: implement a macro expander with support for quote/unquote:

trace_macro = Sirop.macro do |ast| source = Sirop.to_source(ast) quote do result = unquote(ast) puts “The result of #{source} is: #{result}” result end end

def add(x, y) trace(x + y) end

Sirop.expand_macros(method(:add), trace: trace_macro)

The example is trivial and contrived, but I suddenly understand how such an interface could be used to actually generate code in Papercraft. I wrote up an issue for this, and hopefully I’ll have some time to work on this in January.