11 releases
0.2.0-alpha.4 | Apr 7, 2020 |
---|---|
0.2.0-alpha.3 | Oct 1, 2019 |
0.2.0-alpha.2 | Sep 23, 2019 |
0.1.6 | Jun 6, 2019 |
0.1.3 | Jul 20, 2018 |
#159 in #thread-pool
93 downloads per month
Used in tokio-reactor
27KB
426 lines
tokio-io-pool
This crate provided a thread pool for executing short, I/O-heavy futures efficiently.
It is no longer necessary following the scheduler
improvements in tokio 0.2.0-alpha.7
, which handle concurrent I/O on many sockets much better
than the old scheduler did. Tokio 0.2 also does not allow the same hooks
to provide a custom scheduler, so even if it were necessary, updating
tokio-io-pool
to work as "transparently" as it did with tokio 0.1
would be difficult. For that reason, this project has been discontinued.
If you find an issue with tokio's performance, file it as a tokio bug :)
lib.rs
:
This crate provides a thread pool for executing short, I/O-heavy futures efficiently.
The standard Runtime
provided by tokio
uses a thread-pool to allow concurrent execution of
compute-heavy futures. However, its work-stealing makes it so that futures may be executed on
different threads to where their reactor are running, which results in unnecessary
synchronization, and thus lowers the achievable throughput. While this trade-off works well for
many asynchronous applications, since it spreads load more evenly, it is not a great fit for
high-performance I/O bound applications where the cost of synchronizing threads is high. This
can happen, for example, if your application performs frequent but small I/O operations.
This crate provides an alternative implementation of a futures-based thread pool. It spawns a
pool of threads that each runs a tokio::runtime::current_thread::Runtime
(and thus each have
an I/O reactor of their own), and spawns futures onto the pool by assigning the future to
threads round-robin. Once a future has been spawned onto a thread, it, and any child futures it
may produce through tokio::spawn
, remain under the control of that same thread.
In general, you should use tokio-io-pool
only if you perform a lot of very short I/O
operations on many futures, and find that you are bottlenecked by work-stealing or reactor
notifications with the regular tokio
runtime. If you are unsure what to use, start with the
tokio
runtime.
Be aware that this pool does not support the
blocking
function
since it is not supported by the underlying
current_thread::Runtime
. Hopefully this will be rectified down the line.
There is some discussion around trying to merge this pool into tokio
proper; that effort is
tracked in tokio-rs/tokio#486.
Examples
use tokio::prelude::*;
use tokio::io::AsyncReadExt;
use tokio::net::TcpListener;
fn main() {
let server = async move {
// Bind the server's socket.
let mut listener = TcpListener::bind("127.0.0.1:12345").await.expect("unable to bind TCP listener");
// Pull out a stream of sockets for incoming connections
loop {
let (sock, _) = listener.accept().await.expect("acccept failed");
tokio::spawn(async move {
let mut sock = sock;
let (mut reader, mut writer) = sock.split();
let bytes_copied = reader.copy(&mut writer);
let n = bytes_copied.await.expect("I/O error");
println!("wrote {} bytes", n);
});
}
};
// Start the Tokio runtime
tokio_io_pool::run(server);
}
Dependencies
~4.5MB
~68K SLoC