2 unstable releases
0.2.1 | Mar 6, 2025 |
---|---|
0.2.0 |
|
0.1.0 | Feb 19, 2025 |
#1486 in Asynchronous
446 downloads per month
130KB
2.5K
SLoC
local-runtime
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.
In addition, This crate provides async timers and an async adapter for standard
I/O types, similar to
async-io
.
Note: Currently, Windows is not supported.
See the docs for more info.
lib.rs
:
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>(())
})?;
Dependencies
~2–11MB
~137K SLoC