Evt
The Event Library that designed for Ruby 3.0 Fiber Scheduler.
This gem is still under development, APIs and features are not stable. Advices and PRs are highly welcome.
Features
IO Backend Support
Linux | Windows | macOS | FreeBSD | |
---|---|---|---|---|
io_uring | ||||
epoll | ||||
kqueue | ||||
IOCP | ||||
Ruby (IO.select ) |
- when liburing is installed. (Currently fixing)
- when kernel version >= 2.6.9
- WOULD NOT WORK until
FILE_FLAG_OVERLAPPED
is included in I/O initialization process. - Some I/Os are not able to be nonblock under Windows. Using POSIX select, SLOW. See Scheduler Docs.
kqueue
performance in Darwin is very poor. MAY BE DISABLED IN THE FUTURE.- Using poll
Benchmark
The benchmark is running under v0.3.6
version. See example.rb
in midori for test code, the test is running under a single-thread server.
The test command is wrk -t4 -c8192 -d30s http://localhost:8080
.
All the systems have set their file descriptor limit to maximum.
On systems raising "Fiber unable to allocate memory", sudo sysctl -w vm.max_map_count=1000000
is set.
OS | CPU | Memory | Backend | req/s |
---|---|---|---|---|
Linux | Ryzen 2700x | 64GB | epoll | 2035742.59 |
Linux | Ryzen 2700x | 64GB | io_uring | require fixes |
Linux | Ryzen 2700x | 64GB | IO.select (using poll) | 1837640.54 |
macOS | i7-6820HQ | 16GB | kqueue | 257821.78 |
macOS | i7-6820HQ | 16GB | IO.select (using poll) | 338392.12 |
We also test the server with Redis request, with a monkey-patched redis library. The example code is following:
require 'evt'
require 'midori'
require 'midori-contrib/redic'
Fiber.set_scheduler Evt::Scheduler.new
REDIS = Redic.new
class HelloWorldAPI < Midori::API
get '/' do
REDIS.call 'GET', 'foo'
end
end
Fiber.schedule do
Midori::Runner.new(HelloWorldAPI).start
end
The benchmark result is as following:
OS | CPU | Memory | Backend | req/s |
---|---|---|---|---|
Linux | Ryzen 2700x | 64GB | epoll | 378060.30 |
macOS | i7-6820HQ | 16GB | kqueue | 204460.32 |
Install
gem install evt
Usage
require 'evt'
rd, wr = IO.pipe
scheduler = Evt::Scheduler.new
Fiber.set_scheduler scheduler
Fiber.schedule do
message = rd.read(20)
puts message
rd.close
end
Fiber.schedule do
wr.write("Hello World")
wr.close
end
# "Hello World"
Roadmap
- Support epoll/kqueue/select
- Upgrade to the latest Scheduler API
- Support io_uring
- Support iov features of io_uring
- Support IOCP (NOT ENABLED YET)
- Setup tests with Ruby 3
- Selectable backend compilation by environment variable
- Support IOCP with iov features
- Setup more tests for production purpose
- Documentation for usages