Ruby 3 brought us exciting new ways of boosting concurrent execution. While the Ractor
is enjoying most of the spotlight, I’m personally more excited about Fiber.set_scheduler
. I’m not going to spend time explaining when Samuel Williams, who introduced it, delivered a great talk about it during the 2020’ RubyKaigi (virtual) conference.
As I was learning about Ruby’s new Fiber
scheduler, I came across nio4r
. This gem provides a cross-platform stateful I/O selector API for Ruby. It’s at the heart of projects such as puma
and actioncable
. Internally, it uses the system’s asynchronous I/O primitives.
Modern operating systems provide a multitude of options when it comes to asynchronous I/O APIs, and in Linux land io_uring
is the newest kid on the block. Synthetic benchmarks show very promising results. nio4r
actually uses libev
underneath which only recently - as of version 4.33 - started shipping with (experimental) support for io_uring
. I noticed that nio4r
didn’t yet include support for io_uring
so I went ahead and added it by upgrading its libev
distribution. Following libev
’s implementation, it’s marked as experimental and it will never be automatically selected as the best backend available on the system. We will hopefully get there soon.
I then noticed that puma
didn’t provide any way of specifying the desired I/O selector backend, and so again I went ahead added it.
Small improvements that were fun to work on!