Crate local_runtime

Source
Expand description

Thread-local async runtime

This crate provides an async runtime that runs entirely within the current thread. As such, it can run futures that are !Send and non-static. If no future is able to make progress, the runtime will suspend the current thread until a future is ready to be polled.

To actually run a future, see block_on or Executor::block_on, which drives the future to completion on the current thread.

In addition, This crate provides async timers and an async adapter for standard I/O types, similar to async-io.

§Implementation

Task wakeups are handled by a thread-local reactor, which keeps track of all I/O events and timers in the current thread along with their associated wakers. Waiting for the reactor is done by block_on, without needing a separate thread.

The implementation of the reactor depends on the platform. On Unix systems, the reactor uses poll. Currently, Windows is not supported.

§Concurrency

The Executor can spawn tasks that run concurrently on the same thread. Alternatively, this crate provides macros such as join and merge_futures for concurrent execution.

§Compatibility

Unlike other runtimes, local_runtime doesn’t run the reactor in the background, instead relying on block_on to run the reactor while polling the future. Since leaf futures from this crate, such as Async and timers, rely on the reactor to wake up, they can only be driven by block_on, and are not compatible with other runtimes.

§Examples

Listen for connections on a local port, while concurrently making connections to localhost. Return with error if any operation fails.

use std::{net::{TcpStream, TcpListener}, time::Duration, io};
use futures_lite::{AsyncReadExt, AsyncWriteExt, StreamExt};
use local_runtime::{io::Async, time::sleep, Executor};

let ex = Executor::new();
ex.block_on(async {
    let listener = Async::<TcpListener>::bind(([127, 0, 0, 1], 0))?;
    let addr = listener.get_ref().local_addr()?;

    // Run this task in the background
    let _bg = ex.spawn(async move {
        // Listen for connections on local port
        loop {
            let (mut stream, _) = listener.accept().await?;
            let mut buf = [0u8; 5];
            stream.read_exact(&mut buf).await?;
            assert_eq!(&buf, b"hello");
        }
        Ok::<_, io::Error>(())
    });

    // Connect to the listener repeatedly with 50us delay
    loop {
        let mut stream = Async::<TcpStream>::connect(addr).await?;
        stream.write_all(b"hello").await?;
        sleep(Duration::from_micros(500)).await;
    }
    Ok::<_, io::Error>(())
})?;

Re-exports§

pub use io::Async;

Modules§

io
Async I/O primitives
time
Async timekeeping

Macros§

join
Poll multiple futures concurrently, returning a future that outputs an array of all results once all futures have completed.
merge_futures
Poll the futures concurrently and return their outputs as a stream.
merge_streams
Run the streams concurrently and return their outputs one at a time.

Structs§

Executor
An async executor that can spawn tasks
TaskHandle
A handle to a spawned task

Functions§

block_on
Drives a future to completion on the current thread, processing I/O events when idle.