IOU: io_uring for Ruby
What is IOU?
IOU is a Ruby gem for working with the io_uring API. IOU provides a simple and
idiomatic API for working with io_uring. IOU does not make any assumptions about
the concurrency model in your application. It can be used in multi-threaded,
multi-fibered, or callback-based apps. It largely follows the
liburing API, but provides certain
Ruby-esque amenities to make it easier to use io_uring in Ruby apps.
Features
- Prepare and submit operations: accept, read, write, timeout, nop.
- Cancel operations.
- Multishot timeout, accept, read.
- Setup buffer ring for multishot read (provides a nice boost for read performance).
- Associate arbitrary data with operations.
- Run callback on completion of operations.
- Emit arbitrary values for in-app signalling.
Basic Usage
Operations are performed by preparing them (using the different #prep_xxx
methods), submitting them, then waiting or polling for completion of those
operations. Here's a simple example of how IOU is used:
ring = IOU::Ring.new
ring.prep_timeout(interval: 3)
ring.submit
ring.wait_for_completion
Cancelling operations
Any operation can be cancelled by calling #prep_cancel
:
id = ring.prep_timeout(interval: 3)
...
ring.prep_cancel(id)
Callback-style completions
Callback-style handling of completions can be done using #process_completions
:
timeout_id = ring.prep_timeout(interval: 3)
ring.submit
ring.process_completions(true) do |completion|
if completion[:id] == timeout_id
puts "timeout elapsed!"
end
end
timeout_id = ring.prep_timeout(interval: 3) do
puts "timeout elapsed"
end
ring.process_completions(true)
I/O with IOU
I/O operations, such as read
, write
, recv
, send
, accept
etc are done
using raw fd's.
ring.prep_write(fd: STDOUT.fileno, buffer: 'Hello world!')
ring.submit
ring.wait_for_completion
Examples
Examples for using IOU can be found in the examples directory:
- Echo server
- HTTP server
- Event loop (in the style of EventMachine)
- Fiber-based concurrency