Uringy
Writing concurrent code in Rust doesn't need to be painful. Uringy is a runtime that combines structured concurrency, a single-threaded design, and Linux's io_uring. Intended for server applications, from simple single-threaded to highly scalable thread-per-core designs.
Goals
Simple API
- Familiar blocking syntax which closely mirrors Rust's standard library
- Avoid
async/await's limitations and footguns - Easy to learn with stellar documentation and examples
- Spawn with non-
Sendand non-'statictypes - Leak-free hierarchy of fibers with first-class cancellation support
Performant
- Issue non-blocking, batched, zero-copy syscalls with io_uring
- Efficient context switching with cooperative multitasking
- Atomic-free scheduler, parallelized manually if required
Quick to compile
- Compile only what you need using [cargo features](#Compile Time Flags)
- Minimal dependencies
- Minimal use of macros
Quick Start
Install Rust and create a new cargo project.
Add uringy as a dependency: cargo add uringy
Then replace src/main.rs with:
// No need for async main
// No need for async functions
And run your project using: cargo run --release
If you're using macOS, use a Linux virtual machine or a docker container. If you're using Windows, use WSL.
For more, check out the examples directory.
Compile Time Flags
There are currently no cargo flags.
Comparison with Other Runtimes
| std thread | uringy fiber | tokio task | |
|---|---|---|---|
| OS support | all | Linux | most |
| IO interface | blocking | io_uring | epoll + thread pool |
| function color | sync | sync | sync and async |
| start | N/A | 27 μs | 27.5 μs (3.5 μs using current thread scheduler) |
| spawn | 9828 ns | 59 ns | 907 ns (58ns using current thread scheduler) |
spawn Send bound |
yes | no | yes, unless using LocalSet |
spawn 'static bound |
yes, unless using scope | yes, unless using scope | yes |
| stack size | virtual 8MB (configurable), 4KB increments | virtual 128KB (configurable), 4KB increments | perfectly sized |
| stack limitations | may overflow | may overflow | can't use recursion |
| context switch | 1405 ns | 60 ns | 1328 ns (308 ns using current thread scheduler) |
| multi-tasking | preemptive | cooperative | mostly cooperative |
| structured concurrency | no guarantees | parent fiber outlives its children | no guarantees |
| runs until | main thread completes | all fibers complete | block_on completes |
| parallelism | automatic | manual | automatic, unless using current thread scheduler |
| userspace scheduler | N/A | minimal | work stealing |
| cancellation | using esoteric unix signals | first class, voluntary | leaks memory, causes bugs |
Supported Rust Versions
The MSRV is 1.70.0 (released in June 2023).
Check your Rust version by running rustc --version in a terminal.
Supported Linux Kernel Versions
The minimum kernel version is 6.1 (released in December 2022).
Check your kernel version by running uname -r in a terminal.
License
Uringy is licensed under the MIT license. It's a permissive license, which basically means you can do whatever you want.