Uringy

![website] ![github] ![crates-io] ![docs-rs] ![license]

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

Performant

Quick to compile

Quick Start

Install Rust and create a new cargo project.

Add uringy as a dependency: cargo add uringy

Then replace src/main.rs with: ```rust // No need for async main

[uringy::start]

fn main() { let handle = uringy::fiber::spawn(|| tcpechoserver(9000)); // No need for async block

uringy::signals().filter(Signal::is_terminal).next().unwrap();
uringy::println!("gracefully shutting down");
handle.cancel(); // Cancellation propagates throughout the entire fiber hierarchy

// Automatically waits for all fibers to complete

}

// No need for async functions fn tcpechoserver(port: u16) { let listener = uringy::net::TcpListener::bind(("0.0.0.0", port)).unwrap(); uringy::println!("listening for TCP connections on port {port}"); // No need for .await let mut connections = listener.incoming(); while let Ok((stream, )) = connections.next() { uringy::fiber::spawn(move || handleconnection(stream)); } }

fn handle_connection(tcp: TcpStream) { let (mut r, mut w) = stream.split(); let _ = std::io::copy(&mut r, &mut w); // TcpStream implements std::io's Read and Write } ```

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 | iouring | 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 | blockon 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.