#async #async-io #io

tokio_wasi

An event-driven, non-blocking I/O platform for writing asynchronous I/O backed applications

6 stable releases

1.25.2 Jun 6, 2023
1.25.1 Feb 11, 2023
1.23.0 Jan 3, 2023
1.21.3 Nov 8, 2022
1.21.2 Sep 30, 2022

#157 in Asynchronous

Download history 456/week @ 2023-12-15 512/week @ 2023-12-22 399/week @ 2023-12-29 589/week @ 2024-01-05 3118/week @ 2024-01-12 6342/week @ 2024-01-19 10274/week @ 2024-01-26 6658/week @ 2024-02-02 7827/week @ 2024-02-09 4040/week @ 2024-02-16 883/week @ 2024-02-23 1537/week @ 2024-03-01 835/week @ 2024-03-08 1294/week @ 2024-03-15 4916/week @ 2024-03-22 1285/week @ 2024-03-29

8,668 downloads per month
Used in 37 crates (27 directly)

MIT license

2.5MB
36K SLoC

Tokio for WebAssembly

A runtime for writing reliable, asynchronous, and slim applications with the Rust programming language. This is a fork of the original tokio so that it can be compiled into WebAssembly. The WebAssembly app can run inside the WasmEdge Runtime as a lightweight and secure alternative to natively compiled apps in Linux container.

  • Fast: Tokio's zero-cost abstractions give you bare-metal performance.

  • Reliable: Tokio leverages Rust's ownership, type system, and concurrency model to reduce bugs and ensure thread safety.

  • Scalable: Tokio has a minimal footprint, and handles backpressure and cancellation naturally.

Overview

Tokio is an event-driven, non-blocking I/O platform for writing asynchronous applications with the Rust programming language. At a high level, it provides a few major components:

  • A multithreaded, work-stealing based task scheduler.
  • A reactor backed by the operating system's event queue (epoll, kqueue, IOCP, etc...).
  • Asynchronous TCP and UDP sockets.

These components provide the runtime components necessary for building an asynchronous application.

Example

A basic TCP echo server with Tokio.

Make sure you activated the full features of the tokio crate on Cargo.toml:

[dependencies]
tokio_wasi = { version = "1.25", features = ["full"] }

Then, on your main.rs:

use tokio::net::TcpListener;
use tokio::io::{AsyncReadExt, AsyncWriteExt};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let listener = TcpListener::bind("127.0.0.1:8080").await?;

    loop {
        let (mut socket, _) = listener.accept().await?;

        tokio::spawn(async move {
            let mut buf = [0; 1024];

            // In a loop, read data from the socket and write the data back.
            loop {
                let n = match socket.read(&mut buf).await {
                    // socket closed
                    Ok(n) if n == 0 => return,
                    Ok(n) => n,
                    Err(e) => {
                        eprintln!("failed to read from socket; err = {:?}", e);
                        return;
                    }
                };

                // Write the data back
                if let Err(e) = socket.write_all(&buf[0..n]).await {
                    eprintln!("failed to write to socket; err = {:?}", e);
                    return;
                }
            }
        });
    }
}

More examples can be found here. For a larger "real world" example, see the mini-redis repository.

License

This project is licensed under the MIT license.

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in Tokio by you, shall be licensed as MIT, without any additional terms or conditions.

Dependencies

~0–12MB
~114K SLoC