reactor: rename tokio-reactor -> tokio-net (#1450)

* reactor: rename tokio-reactor -> tokio-net

This is in preparation for #1264
This commit is contained in:
Carl Lerche
2019-08-15 11:04:58 -07:00
committed by GitHub
parent 7b6438a172
commit 8538c25170
48 changed files with 111 additions and 511 deletions
+1 -1
View File
@@ -8,8 +8,8 @@ members = [
"tokio-fs",
"tokio-io",
"tokio-macros",
"tokio-net",
"tokio-process",
"tokio-reactor",
"tokio-signal",
"tokio-sync",
"tokio-test",
+6 -10
View File
@@ -129,10 +129,7 @@ have greater guarantees of stability.
The crates included as part of Tokio are:
* [`tokio-current-thread`]: Schedule the execution of futures on the current
thread.
* [`tokio-executor`]: Task execution related traits and utilities.
* [`tokio-executor`]: Task executors and related utilities.
* [`tokio-fs`]: Filesystem (and standard in / out) APIs.
@@ -142,20 +139,19 @@ The crates included as part of Tokio are:
* [`tokio-macros`]: Macros for usage with Tokio.
* [`tokio-reactor`]: Event loop that drives I/O resources (like TCP and UDP
* [`tokio-net`]: Event loop that drives I/O resources (like TCP and UDP
sockets).
* [`tokio-tcp`]: TCP bindings for use with `tokio-io` and `tokio-reactor`.
* [`tokio-tcp`]: TCP listener and acceptor.
* [`tokio-threadpool`]: Schedules the execution of futures across a pool of
threads.
* [ `tokio-timer`]: Time related APIs.
* [`tokio-udp`]: UDP bindings for use with `tokio-io` and `tokio-reactor`.
* [`tokio-udp`]: UDP socket.
* [`tokio-uds`]: Unix Domain Socket bindings for use with `tokio-io` and
`tokio-reactor`.
* [`tokio-uds`]: Unix Domain Socket bindings.
[`tokio-codec`]: tokio-codec
[`tokio-current-thread`]: tokio-current-thread
@@ -163,7 +159,7 @@ The crates included as part of Tokio are:
[`tokio-fs`]: tokio-fs
[`tokio-io`]: tokio-io
[`tokio-macros`]: tokio-macros
[`tokio-reactor`]: tokio-reactor
[`tokio-net`]: tokio-net
[`tokio-tcp`]: tokio-tcp
[`tokio-threadpool`]: tokio-threadpool
[`tokio-timer`]: tokio-timer
+3 -2
View File
@@ -30,7 +30,6 @@ jobs:
- codec
- fs
- io
- reactor
- rt-full
- net
- sync
@@ -48,8 +47,8 @@ jobs:
rust: $(nightly)
crates:
tokio-fs: []
tokio-net: []
tokio-process: []
tokio-reactor: []
tokio-signal: []
tokio-tcp:
- async-traits
@@ -87,6 +86,8 @@ jobs:
crates:
ui-tests:
- executor-without-current-thread
- tokio-no-features
- tokio-with-net
# - template: ci/azure-cargo-check.yml
# parameters:
+2 -1
View File
@@ -7,7 +7,8 @@ tokio-codec = { path = "tokio-codec" }
tokio-executor = { path = "tokio-executor" }
tokio-fs = { path = "tokio-fs" }
tokio-io = { path = "tokio-io" }
tokio-reactor = { path = "tokio-reactor" }
tokio-macros = { path = "tokio-macros" }
tokio-net = { path = "tokio-net" }
tokio-signal = { path = "tokio-signal" }
tokio-sync = { path = "tokio-sync" }
tokio-threadpool = { path = "tokio-threadpool" }
@@ -1,5 +1,5 @@
[package]
name = "tokio-reactor"
name = "tokio-net"
# When releasing to crates.io:
# - Remove path dependencies
# - Update html_root_url.
@@ -14,7 +14,7 @@ license = "MIT"
readme = "README.md"
repository = "https://github.com/tokio-rs/tokio"
homepage = "https://tokio.rs"
documentation = "https://docs.rs/tokio-reactor/0.2.0-alpha.1/tokio_reactor"
documentation = "https://docs.rs/tokio-net/0.2.0-alpha.1/tokio_net"
description = """
Event loop that drives Tokio I/O resources.
"""
@@ -1,4 +1,4 @@
#![doc(html_root_url = "https://docs.rs/tokio-reactor/0.2.0-alpha.1")]
#![doc(html_root_url = "https://docs.rs/tokio-net/0.2.0-alpha.1")]
#![warn(
missing_debug_implementations,
missing_docs,
@@ -23,7 +23,7 @@
//! resources that are driven by the reactor.
//!
//! Application authors will not use this crate directly. Instead, they will use the
//! `tokio` crate. Library authors should only depend on `tokio-reactor` if they
//! `tokio` crate. Library authors should only depend on `tokio-net` if they
//! are building a custom I/O resource.
//!
//! For more details, see [reactor module] documentation in the Tokio crate.
@@ -1,4 +1,7 @@
use crate::{Handle, Registration};
use tokio_io::{AsyncRead, AsyncWrite};
use futures_core::ready;
use mio;
use mio::event::Evented;
@@ -9,7 +12,6 @@ use std::pin::Pin;
use std::sync::atomic::AtomicUsize;
use std::sync::atomic::Ordering::Relaxed;
use std::task::{Context, Poll};
use tokio_io::{AsyncRead, AsyncWrite};
/// Associates an I/O resource that implements the [`std::io::Read`] and/or
/// [`std::io::Write`] traits with the reactor that drives it.
@@ -53,7 +55,7 @@ use tokio_io::{AsyncRead, AsyncWrite};
/// [`clear_read_ready`].
///
/// ```rust
/// use tokio_reactor::PollEvented;
/// use tokio_net::PollEvented;
///
/// use futures_core::ready;
/// use mio::Ready;
+1 -1
View File
@@ -24,7 +24,7 @@ futures-core-preview = "=0.3.0-alpha.18"
futures-util-preview = "=0.3.0-alpha.18"
log = "0.4"
tokio-io = { version = "=0.2.0-alpha.1", path = "../tokio-io", features = ["util"] }
tokio-reactor = { version = "=0.2.0-alpha.1", path = "../tokio-reactor" }
tokio-net = { version = "=0.2.0-alpha.1", path = "../tokio-net" }
[dev-dependencies.tokio]
version = "=0.2.0-alpha.1"
+4 -5
View File
@@ -132,22 +132,21 @@ extern crate lazy_static;
#[macro_use]
extern crate log;
use std::io;
use std::process::{Command, ExitStatus, Output, Stdio};
use tokio_io::{AsyncRead, AsyncReadExt, AsyncWrite};
use tokio_net::Handle;
use futures_core::future::TryFuture;
use futures_util::future;
use futures_util::future::FutureExt;
use futures_util::try_future::TryFutureExt;
use kill::Kill;
use std::fmt;
use std::future::Future;
use std::io;
use std::pin::Pin;
use std::process::{Command, ExitStatus, Output, Stdio};
use std::task::Context;
use std::task::Poll;
use tokio_io::{AsyncRead, AsyncReadExt, AsyncWrite};
use tokio_reactor::Handle;
#[path = "unix/mod.rs"]
#[cfg(unix)]
+4 -2
View File
@@ -28,6 +28,10 @@ use self::orphan::{AtomicOrphanQueue, OrphanQueue, Wait};
use self::reap::Reaper;
use super::SpawnedChild;
use crate::kill::Kill;
use tokio_net::{Handle, PollEvented};
use tokio_signal::unix::{Signal, SignalKind};
use mio::event::Evented;
use mio::unix::{EventedFd, UnixReady};
use mio::{Poll as MioPoll, PollOpt, Ready, Token};
@@ -39,8 +43,6 @@ use std::pin::Pin;
use std::process::{self, ExitStatus};
use std::task::Context;
use std::task::Poll;
use tokio_reactor::{Handle, PollEvented};
use tokio_signal::unix::{Signal, SignalKind};
impl Wait for process::Child {
fn id(&self) -> u32 {
+1 -1
View File
@@ -33,7 +33,7 @@ use futures_util::future::FutureExt;
use super::SpawnedChild;
use mio_named_pipes::NamedPipe;
use tokio_reactor::{Handle, PollEvented};
use tokio_net::{Handle, PollEvented};
use tokio_sync::oneshot;
use winapi::shared::minwindef::*;
use winapi::shared::winerror::*;
-133
View File
@@ -1,133 +0,0 @@
#![feature(test)]
#![warn(rust_2018_idioms)]
/*
extern crate test;
const NUM_YIELD: usize = 500;
const TASKS_PER_CPU: usize = 100;
mod threadpool {
use super::*;
use std::sync::mpsc;
use futures::{future, Async};
use test::Bencher;
use tokio::runtime::Runtime;
use tokio_reactor::Registration;
#[bench]
fn notify_many(b: &mut Bencher) {
let mut rt = Runtime::new().unwrap();
let tasks = TASKS_PER_CPU * num_cpus::get();
b.iter(|| {
let (tx, rx) = mpsc::channel();
rt.block_on::<_, (), ()>(future::lazy(move || {
for _ in 0..tasks {
let tx = tx.clone();
tokio::spawn(future::lazy(move || {
let (r, s) = mio::Registration::new2();
let registration = Registration::new();
registration.register(&r).unwrap();
let mut rem = NUM_YIELD;
let mut r = Some(r);
let tx = tx.clone();
tokio::spawn(future::poll_fn(move || loop {
let is_ready = registration.poll_read_ready().unwrap().is_ready();
if is_ready {
rem -= 1;
if rem == 0 {
r.take().unwrap();
tx.send(()).unwrap();
return Ok(Async::Ready(()));
}
} else {
s.set_readiness(mio::Ready::readable()).unwrap();
return Ok(Async::NotReady);
}
}));
Ok(())
}));
}
Ok(())
}))
.unwrap();
for _ in 0..tasks {
rx.recv().unwrap();
}
})
}
}
mod io_pool {
use super::*;
use std::sync::mpsc;
use futures::{future, Async};
use test::Bencher;
use tokio_io_pool::Runtime;
use tokio_reactor::Registration;
#[bench]
fn notify_many(b: &mut Bencher) {
let mut rt = Runtime::new();
let tasks = TASKS_PER_CPU * num_cpus::get();
b.iter(|| {
let (tx, rx) = mpsc::channel();
rt.block_on::<_, (), ()>(future::lazy(move || {
for _ in 0..tasks {
let tx = tx.clone();
tokio::spawn(future::lazy(move || {
let (r, s) = mio::Registration::new2();
let registration = Registration::new();
registration.register(&r).unwrap();
let mut rem = NUM_YIELD;
let mut r = Some(r);
let tx = tx.clone();
tokio::spawn(future::poll_fn(move || loop {
let is_ready = registration.poll_read_ready().unwrap().is_ready();
if is_ready {
rem -= 1;
if rem == 0 {
r.take().unwrap();
tx.send(()).unwrap();
return Ok(Async::Ready(()));
}
} else {
s.set_readiness(mio::Ready::readable()).unwrap();
return Ok(Async::NotReady);
}
}));
Ok(())
}));
}
Ok(())
}))
.unwrap();
for _ in 0..tasks {
rx.recv().unwrap();
}
})
}
}
*/
+1 -1
View File
@@ -23,8 +23,8 @@ categories = ["asynchronous"]
futures-core-preview = "=0.3.0-alpha.18"
futures-util-preview = "=0.3.0-alpha.18"
lazy_static = "1"
tokio-reactor = { version = "=0.2.0-alpha.1", path = "../tokio-reactor" }
tokio-io = { version = "=0.2.0-alpha.1", path = "../tokio-io" }
tokio-net = { version = "=0.2.0-alpha.1", path = "../tokio-net" }
tokio-sync = { version = "=0.2.0-alpha.1", path = "../tokio-sync" }
[target.'cfg(unix)'.dependencies]
+3 -1
View File
@@ -2,11 +2,13 @@
use crate::unix::Signal as Inner;
#[cfg(windows)]
use crate::windows::Event as Inner;
use tokio_net::Handle;
use futures_core::stream::Stream;
use std::io;
use std::pin::Pin;
use std::task::{Context, Poll};
use tokio_reactor::Handle;
/// Represents a stream which receives "ctrl-c" notifications sent to the process.
///
+1 -1
View File
@@ -18,7 +18,7 @@ use mio_uds::UnixStream;
use std::future::Future;
use std::task::{Context, Poll};
use tokio_io::AsyncRead;
use tokio_reactor::{Handle, PollEvented};
use tokio_net::{Handle, PollEvented};
use tokio_sync::mpsc::{channel, Receiver};
use crate::registry::{globals, EventId, EventInfo, Globals, Init, Storage};
+6 -6
View File
@@ -7,21 +7,21 @@
#![cfg(windows)]
use crate::registry::{globals, EventId, EventInfo, Init, Storage};
use tokio_net::Handle;
use tokio_sync::mpsc::{channel, Receiver};
use futures_core::stream::Stream;
use std::convert::TryFrom;
use std::io;
use std::pin::Pin;
use std::sync::Once;
use std::task::{Context, Poll};
use futures_core::stream::Stream;
use tokio_reactor::Handle;
use tokio_sync::mpsc::{channel, Receiver};
use winapi::shared::minwindef::*;
use winapi::um::consoleapi::SetConsoleCtrlHandler;
use winapi::um::wincon::*;
use crate::registry::{globals, EventId, EventInfo, Init, Storage};
#[derive(Debug)]
pub(crate) struct OsStorage {
ctrl_c: EventInfo,
+1 -1
View File
@@ -24,7 +24,7 @@ async-traits = []
[dependencies]
tokio-io = { version = "=0.2.0-alpha.1", path = "../tokio-io" }
tokio-reactor = { version = "=0.2.0-alpha.1", path = "../tokio-reactor" }
tokio-net = { version = "=0.2.0-alpha.1", path = "../tokio-net" }
futures-core-preview = "=0.3.0-alpha.18"
futures-util-preview = "=0.3.0-alpha.18"
+3 -2
View File
@@ -1,6 +1,8 @@
#[cfg(feature = "async-traits")]
use super::incoming::Incoming;
use super::TcpStream;
use tokio_net::{Handle, PollEvented};
use futures_core::ready;
use futures_util::future::poll_fn;
use mio;
@@ -9,7 +11,6 @@ use std::fmt;
use std::io;
use std::net::{self, SocketAddr};
use std::task::{Context, Poll};
use tokio_reactor::{Handle, PollEvented};
/// An I/O object representing a TCP socket listening for incoming connections.
///
@@ -259,7 +260,7 @@ impl TryFrom<TcpListener> for mio::net::TcpListener {
/// Consumes value, returning the mio I/O object.
///
/// See [`tokio_reactor::PollEvented::into_inner`] for more details about
/// See [`tokio_net::PollEvented::into_inner`] for more details about
/// resource deregistration that happens during the call.
fn try_from(value: TcpListener) -> Result<Self, Self::Error> {
value.io.into_inner()
+6 -4
View File
@@ -2,6 +2,10 @@ use crate::split::{
split, split_mut, TcpStreamReadHalf, TcpStreamReadHalfMut, TcpStreamWriteHalf,
TcpStreamWriteHalfMut,
};
use tokio_io::{AsyncRead, AsyncWrite};
use tokio_net::{Handle, PollEvented};
use bytes::{Buf, BufMut};
use futures_core::ready;
use futures_util::future::poll_fn;
@@ -16,8 +20,6 @@ use std::net::{self, Shutdown, SocketAddr};
use std::pin::Pin;
use std::task::{Context, Poll};
use std::time::Duration;
use tokio_io::{AsyncRead, AsyncWrite};
use tokio_reactor::{Handle, PollEvented};
/// An I/O object representing a TCP stream connected to a remote endpoint.
///
@@ -123,7 +125,7 @@ impl TcpStream {
///
/// ```no_run
/// use tokio::net::TcpStream;
/// use tokio_reactor::Handle;
/// use tokio_net::Handle;
///
/// # fn dox() -> std::io::Result<()> {
/// let std_stream = std::net::TcpStream::connect("127.0.0.1:34254")?;
@@ -799,7 +801,7 @@ impl TryFrom<TcpStream> for mio::net::TcpStream {
/// Consumes value, returning the mio I/O object.
///
/// See [`tokio_reactor::PollEvented::into_inner`] for more details about
/// See [`tokio_net::PollEvented::into_inner`] for more details about
/// resource deregistration that happens during the call.
fn try_from(value: TcpStream) -> Result<Self, Self::Error> {
value.io.into_inner()
+1 -2
View File
@@ -21,8 +21,7 @@ categories = ["asynchronous"]
[dependencies]
tokio-codec = { version = "=0.2.0-alpha.1", path = "../tokio-codec" }
# tokio-io = { version = "0.2.0", path = "../tokio-io" }
tokio-reactor = { version = "=0.2.0-alpha.1", path = "../tokio-reactor" }
tokio-net = { version = "=0.2.0-alpha.1", path = "../tokio-net" }
bytes = "0.4.12"
mio = "0.6.14"
+2 -2
View File
@@ -1,6 +1,6 @@
use super::split::{split, UdpSocketRecvHalf, UdpSocketSendHalf};
use tokio_reactor::{Handle, PollEvented};
use tokio_net::{Handle, PollEvented};
use futures_core::ready;
use futures_util::future::poll_fn;
@@ -328,7 +328,7 @@ impl TryFrom<UdpSocket> for mio::net::UdpSocket {
/// Consumes value, returning the mio I/O object.
///
/// See [`tokio_reactor::PollEvented::into_inner`] for more details about
/// See [`tokio_net::PollEvented::into_inner`] for more details about
/// resource deregistration that happens during the call.
fn try_from(value: UdpSocket) -> Result<Self, Self::Error> {
value.io.into_inner()
+1 -1
View File
@@ -24,7 +24,7 @@ async-traits = []
[dependencies]
tokio-codec = { version = "=0.2.0-alpha.1", path = "../tokio-codec" }
tokio-reactor = { version = "=0.2.0-alpha.1", path = "../tokio-reactor" }
tokio-net = { version = "=0.2.0-alpha.1", path = "../tokio-net" }
tokio-io = { version = "=0.2.0-alpha.1", path = "../tokio-io" }
bytes = "0.4.8"
+2 -2
View File
@@ -1,4 +1,4 @@
use tokio_reactor::{Handle, PollEvented};
use tokio_net::{Handle, PollEvented};
use futures_core::ready;
use futures_util::future::poll_fn;
@@ -200,7 +200,7 @@ impl TryFrom<UnixDatagram> for mio_uds::UnixDatagram {
/// Consumes value, returning the mio I/O object.
///
/// See [`tokio_reactor::PollEvented::into_inner`] for more details about
/// See [`tokio_net::PollEvented::into_inner`] for more details about
/// resource deregistration that happens during the call.
fn try_from(value: UnixDatagram) -> Result<Self, Self::Error> {
value.io.into_inner()
+2 -2
View File
@@ -1,6 +1,6 @@
use crate::UnixStream;
use tokio_reactor::{Handle, PollEvented};
use tokio_net::{Handle, PollEvented};
use futures_core::ready;
use futures_util::future::poll_fn;
@@ -102,7 +102,7 @@ impl TryFrom<UnixListener> for mio_uds::UnixListener {
/// Consumes value, returning the mio I/O object.
///
/// See [`tokio_reactor::PollEvented::into_inner`] for more details about
/// See [`tokio_net::PollEvented::into_inner`] for more details about
/// resource deregistration that happens during the call.
fn try_from(value: UnixListener) -> Result<Self, Self::Error> {
value.io.into_inner()
+2 -2
View File
@@ -5,7 +5,7 @@ use crate::split::{
use crate::ucred::{self, UCred};
use tokio_io::{AsyncRead, AsyncWrite};
use tokio_reactor::{Handle, PollEvented};
use tokio_net::{Handle, PollEvented};
use bytes::{Buf, BufMut};
use futures_core::ready;
@@ -131,7 +131,7 @@ impl TryFrom<UnixStream> for mio_uds::UnixStream {
/// Consumes value, returning the mio I/O object.
///
/// See [`tokio_reactor::PollEvented::into_inner`] for more details about
/// See [`tokio_net::PollEvented::into_inner`] for more details about
/// resource deregistration that happens during the call.
fn try_from(value: UnixStream) -> Result<Self, Self::Error> {
value.io.into_inner()
+6 -8
View File
@@ -29,7 +29,6 @@ default = [
"fs",
"io",
"net",
"reactor",
"rt-full",
"sync",
"timer",
@@ -38,11 +37,10 @@ default = [
codec = ["io", "tokio-codec", "bytes"]
fs = ["tokio-fs"]
io = ["tokio-io"]
reactor = ["io", "tokio-reactor"]
net = ["reactor", "tcp", "udp", "uds"]
net = ["tcp", "udp", "uds"]
rt-full = [
"num_cpus",
"reactor",
"net",
"sync",
"timer",
"tokio-executor/current-thread",
@@ -51,10 +49,10 @@ rt-full = [
"tracing-core",
]
sync = ["tokio-sync"]
tcp = ["tokio-tcp"]
tcp = ["io", "tokio-net", "tokio-tcp"]
timer = ["tokio-timer"]
udp = ["tokio-udp"]
uds = ["tokio-uds"]
udp = ["io", "tokio-net", "tokio-udp"]
uds = ["io", "tokio-net", "tokio-uds"]
[dependencies]
futures-core-preview = "=0.3.0-alpha.18"
@@ -69,7 +67,7 @@ tokio-fs = { version = "=0.2.0-alpha.1", optional = true, path = "../tokio-fs" }
tokio-io = { version = "=0.2.0-alpha.1", optional = true, features = ["util"], path = "../tokio-io" }
tokio-executor = { version = "=0.2.0-alpha.1", optional = true, path = "../tokio-executor" }
tokio-macros = { version = "=0.2.0-alpha.1", optional = true, path = "../tokio-macros" }
tokio-reactor = { version = "=0.2.0-alpha.1", optional = true, path = "../tokio-reactor" }
tokio-net = { version = "=0.2.0-alpha.1", optional = true, path = "../tokio-net" }
tokio-sync = { version = "=0.2.0-alpha.1", optional = true, path = "../tokio-sync", features = ["async-traits"] }
tokio-threadpool = { version = "=0.2.0-alpha.1", optional = true, path = "../tokio-threadpool" }
tokio-tcp = { version = "=0.2.0-alpha.1", optional = true, path = "../tokio-tcp", features = ["async-traits"] }
-62
View File
@@ -1,62 +0,0 @@
## Examples of how to use Tokio
This directory contains a number of examples showcasing various capabilities of
the `tokio` crate.
All examples can be executed with:
```
cargo run --example $name
```
A high level description of each example is:
* [`hello_world`](hello_world.rs) - a tiny server that writes "hello world" to
all connected clients and then terminates the connection, should help see how
to create and initialize `tokio`.
* [`echo`](echo.rs) - this is your standard TCP "echo server" which accepts
connections and then echos back any contents that are read from each connected
client.
* [`print_each_packet`](print_each_packet.rs) - this server will create a TCP
listener, accept connections in a loop, and put down in the stdout everything
that's read off of each TCP connection.
* [`echo-udp`](echo-udp.rs) - again your standard "echo server", except for UDP
instead of TCP. This will echo back any packets received to the original
sender.
* [`connect`](connect.rs) - this is a `nc`-like clone which can be used to
interact with most other examples. The program creates a TCP connection or UDP
socket and sends all information read on stdin to the remote peer, displaying
any data received on stdout. Often quite useful when interacting with the
various other servers here!
* [`chat`](chat.rs) - this spins up a local TCP server which will broadcast from
any connected client to all other connected clients. You can connect to this
in multiple terminals and use it to chat between the terminals.
* [`chat-combinator`](chat-combinator.rs) - Similar to `chat`, but this uses a
much more functional programming approach using combinators.
* [`proxy`](proxy.rs) - an example proxy server that will forward all connected
TCP clients to the remote address specified when starting the program.
* [`tinyhttp`](tinyhttp.rs) - a tiny HTTP/1.1 server which doesn't support HTTP
request bodies showcasing running on multiple cores, working with futures and
spawning tasks, and finally framing a TCP connection to discrete
request/response objects.
* [`tinydb`](tinydb.rs) - an in-memory database which shows sharing state
between all connected clients, notably the key/value store of this database.
* [`udp-client`](udp-client.rs) - a simple `send_dgram`/`recv_dgram` example.
* [`manual-runtime`](manual-runtime.rs) - manually composing a runtime.
* [`blocking`](blocking.rs) - perform heavy computation in blocking environment.
If you've got an example you'd like to see here, please feel free to open an
issue. Otherwise if you've got an example you'd like to add, please feel free
to make a PR!
-90
View File
@@ -1,90 +0,0 @@
//! An example of using blocking funcion annotation.
//!
//! This example will create 8 "heavy computation" blocking futures and 8
//! non-blocking futures with 4 threads core threads in runtime.
//! Each non-blocking future will print it's id and return immideatly.
//! Each blocking future will print it's id on start, sleep for 1000 ms, print
//! it's id and return.
//!
//! Note how non-blocking threads are executed before blocking threads finish
//! their task.
#![feature(async_await)]
#![warn(rust_2018_idioms)]
use std::pin::Pin;
use std::thread;
use std::time::Duration;
use tokio;
use tokio::prelude::*;
use tokio::runtime::Builder;
use tokio_threadpool::blocking;
/// This future blocks it's poll method for 1000 ms.
struct BlockingFuture {
value: i32,
}
impl Future for BlockingFuture {
type Output = ();
fn poll(self: Pin<&mut Self>, _ctx: &mut task::Context<'_>) -> Poll<Self::Output> {
println!("Blocking begin: {}!", self.value);
// Try replacing this part with commnted code
blocking(|| {
println!("Blocking part annotated: {}!", self.value);
thread::sleep(Duration::from_millis(1000));
println!("Blocking done annotated: {}!", self.value);
}).map(|result| match result {
Ok(result) => result,
Err(err) => panic!("Error in blocing block: {:?}", err),
})
// println!("Blocking part annotated: {}!", self.value);
// thread::sleep(Duration::from_millis(1000));
// println!("Blocking done annotated: {}!", self.value);
// Ok(Async::Ready(()))
}
}
/// This future returns immideatly.
struct NonBlockingFuture {
value: i32,
}
impl Future for NonBlockingFuture {
type Output = ();
fn poll(self: Pin<&mut Self>, _ctx: &mut task::Context<'_>) -> Poll<Self::Output> {
println!("Non-blocking done: {}!", self.value);
Poll::Ready(())
}
}
/// This future spawns child futures.
struct SpawningFuture;
impl Future for SpawningFuture {
type Output = ();
fn poll(self: Pin<&mut Self>, _ctx: &mut task::Context<'_>) -> Poll<Self::Output> {
for i in 0..8 {
let blocking_future = BlockingFuture { value: i };
tokio::spawn(blocking_future);
}
for i in 0..8 {
let non_blocking_future = NonBlockingFuture { value: i };
tokio::spawn(non_blocking_future);
}
Poll::Ready(())
}
}
fn main() {
let spawning_future = SpawningFuture;
let mut runtime = Builder::new()
.core_threads(4)
.build().unwrap();
runtime.block_on_all(spawning_future);
}
-85
View File
@@ -1,85 +0,0 @@
//! An example how to manually assemble a runtime and run some tasks on it.
//!
//! This is closer to the single-threaded runtime than the default tokio one, as it is simpler to
//! grasp. There are conceptually similar, but the multi-threaded one would be more code. If you
//! just want to *use* a single-threaded runtime, use the one provided by tokio directly
//! (`tokio::runtime::current_thread::Runtime::new()`. This is a demonstration only.
//!
//! Note that the error handling is a bit left out. Also, the `run` could be modified to return the
//! result of the provided future.
#![warn(rust_2018_idioms)]
use futures::{future, Future};
use std::io::Error as IoError;
use std::time::{Duration, Instant};
use tokio;
use tokio_current_thread;
use tokio_current_thread::CurrentThread;
use tokio_executor;
use tokio_reactor;
use tokio_reactor::Reactor;
use tokio_timer::timer::{self, Timer};
/// Creates a "runtime".
///
/// This is similar to running `tokio::runtime::current_thread::Runtime::new()`.
fn run<F: Future<Item = (), Error = ()>>(f: F) -> Result<(), IoError> {
// We need a reactor to receive events about IO objects from kernel
let reactor = Reactor::new()?;
let reactor_handle = reactor.handle();
// Place a timer wheel on top of the reactor. If there are no timeouts to fire, it'll let the
// reactor pick up some new external events.
let timer = Timer::new(reactor);
let timer_handle = timer.handle();
// And now put a single-threaded executor on top of the timer. When there are no futures ready
// to do something, it'll let the timer or the reactor generate some new stimuli for the
// futures to continue in their life.
let mut executor = CurrentThread::new_with_park(timer);
// Binds an executor to this thread
let mut enter = tokio_executor::enter().expect("Multiple executors at once");
// This will set the default handle and timer to use inside the closure and run the future.
tokio_reactor::with_default(&reactor_handle, &mut enter, |enter| {
timer::with_default(&timer_handle, enter, |enter| {
// The TaskExecutor is a fake executor that looks into the current single-threaded
// executor when used. This is a trick, because we need two mutable references to the
// executor (one to run the provided future, another to install as the default one). We
// use the fake one here as the default one.
let mut default_executor = tokio_current_thread::TaskExecutor::current();
tokio_executor::with_default(&mut default_executor, enter, |enter| {
let mut executor = executor.enter(enter);
// Run the provided future
executor.block_on(f).unwrap();
// Run all the other futures that are still left in the executor
executor.run().unwrap();
});
});
});
Ok(())
}
fn main() -> Result<(), Box<dyn std::error::Error>> {
run(future::lazy(|| {
// Here comes the application logic. It can spawn further tasks by tokio_current_thread::spawn().
// It also can use the default reactor and create timeouts.
// Connect somewhere. And then do nothing with it. Yes, useless.
//
// This will use the default reactor which runs in the current thread.
let connect = tokio::net::TcpStream::connect(&"127.0.0.1:53".parse().unwrap())
.map(|_| println!("Connected"))
.map_err(|e| println!("Failed to connect: {}", e));
// We can spawn it without requiring Send. This would panic if we run it outside of the
// `run` (or outside of anything else)
tokio_current_thread::spawn(connect);
// We can also create timeouts.
let deadline = tokio::timer::Delay::new(Instant::now() + Duration::from_secs(5))
.map(|()| println!("5 seconds are over"))
.map_err(|e| println!("Failed to wait: {}", e));
// We can spawn on the default executor, which is also the local one.
tokio::executor::spawn(deadline);
Ok(())
}))?;
Ok(())
}
-61
View File
@@ -1,61 +0,0 @@
//! This example leverages `BytesCodec` to create a UDP client and server which
//! speak a custom protocol.
//!
//! Here we're using the codec from tokio-io to convert a UDP socket to a stream of
//! client messages. These messages are then processed and returned back as a
//! new message with a new destination. Overall, we then use this to construct a
//! "ping pong" pair where two sockets are sending messages back and forth.
#![warn(rust_2018_idioms)]
use env_logger;
use std::net::SocketAddr;
use tokio;
use tokio::net::{UdpFramed, UdpSocket};
use tokio::prelude::*;
use tokio_codec::BytesCodec;
fn main() -> Result<(), Box<dyn std::error::Error>> {
let _ = env_logger::init();
let addr: SocketAddr = "127.0.0.1:0".parse()?;
// Bind both our sockets and then figure out what ports we got.
let a = UdpSocket::bind(&addr)?;
let b = UdpSocket::bind(&addr)?;
let b_addr = b.local_addr()?;
// We're parsing each socket with the `BytesCodec` included in `tokio_io`, and then we
// `split` each codec into the sink/stream halves.
let (a_sink, a_stream) = UdpFramed::new(a, BytesCodec::new()).split();
let (b_sink, b_stream) = UdpFramed::new(b, BytesCodec::new()).split();
// Start off by sending a ping from a to b, afterwards we just print out
// what they send us and continually send pings
// let pings = stream::iter((0..5).map(Ok));
let a = a_sink.send(("PING".into(), b_addr)).and_then(|a_sink| {
let mut i = 0;
let a_stream = a_stream.take(4).map(move |(msg, addr)| {
i += 1;
println!("[a] recv: {}", String::from_utf8_lossy(&msg));
(format!("PING {}", i).into(), addr)
});
a_sink.send_all(a_stream)
});
// The second client we have will receive the pings from `a` and then send
// back pongs.
let b_stream = b_stream.map(|(msg, addr)| {
println!("[b] recv: {}", String::from_utf8_lossy(&msg));
("PONG".into(), addr)
});
let b = b_sink.send_all(b_stream);
// Spawn the sender of pongs and then wait for our pinger to finish.
tokio::run({
b.join(a)
.map(|_| ())
.map_err(|e| println!("error = {:?}", e))
});
Ok(())
}
+1 -1
View File
@@ -88,7 +88,7 @@ pub mod io;
#[cfg(any(feature = "tcp", feature = "udp", feature = "uds"))]
pub mod net;
pub mod prelude;
#[cfg(feature = "reactor")]
#[cfg(feature = "tokio-net")]
pub mod reactor;
pub mod stream;
#[cfg(feature = "sync")]
+1 -1
View File
@@ -131,4 +131,4 @@
//! [`std::io::Read`]: https://doc.rust-lang.org/std/io/trait.Read.html
//! [`std::io::Write`]: https://doc.rust-lang.org/std/io/trait.Write.html
pub use tokio_reactor::{Handle, PollEvented, Reactor, Registration, Turn};
pub use tokio_net::{Handle, PollEvented, Reactor, Registration, Turn};
+1 -1
View File
@@ -1,7 +1,7 @@
use crate::runtime::current_thread::Runtime;
use tokio_executor::current_thread::CurrentThread;
use tokio_reactor::Reactor;
use tokio_net::Reactor;
use tokio_timer::clock::Clock;
use tokio_timer::timer::Timer;
+4 -4
View File
@@ -2,7 +2,7 @@ use crate::runtime::current_thread::Builder;
use tokio_executor::current_thread::Handle as ExecutorHandle;
use tokio_executor::current_thread::{self, CurrentThread};
use tokio_reactor::{self, Reactor};
use tokio_net::{self, Reactor};
use tokio_timer::clock::{self, Clock};
use tokio_timer::timer::{self, Timer};
@@ -19,7 +19,7 @@ use std::io;
/// [mod]: index.html
#[derive(Debug)]
pub struct Runtime {
reactor_handle: tokio_reactor::Handle,
reactor_handle: tokio_net::Handle,
timer_handle: timer::Handle,
clock: Clock,
executor: CurrentThread<Parker>,
@@ -93,7 +93,7 @@ impl Runtime {
}
pub(super) fn new2(
reactor_handle: tokio_reactor::Handle,
reactor_handle: tokio_net::Handle,
timer_handle: timer::Handle,
clock: Clock,
executor: CurrentThread<Parker>,
@@ -197,7 +197,7 @@ impl Runtime {
// This will set the default handle and timer to use inside the closure
// and run the future.
tokio_reactor::with_default(&reactor_handle, || {
tokio_net::with_default(&reactor_handle, || {
clock::with_default(clock, || {
timer::with_default(&timer_handle, || {
// The TaskExecutor is a fake executor that looks into the
+3 -3
View File
@@ -2,7 +2,7 @@
//! `block_on` work.
use tokio_executor::current_thread::CurrentThread;
use tokio_reactor::Reactor;
use tokio_net::Reactor;
use tokio_sync::oneshot;
use tokio_timer::clock::Clock;
use tokio_timer::timer::{self, Timer};
@@ -11,7 +11,7 @@ use std::{io, thread};
#[derive(Debug)]
pub(crate) struct Background {
reactor_handle: tokio_reactor::Handle,
reactor_handle: tokio_net::Handle,
timer_handle: timer::Handle,
shutdown_tx: Option<oneshot::Sender<()>>,
thread: Option<thread::JoinHandle<()>>,
@@ -44,7 +44,7 @@ pub(crate) fn spawn(clock: &Clock) -> io::Result<Background> {
}
impl Background {
pub(super) fn reactor(&self) -> &tokio_reactor::Handle {
pub(super) fn reactor(&self) -> &tokio_net::Handle {
&self.reactor_handle
}
+1 -2
View File
@@ -1,7 +1,6 @@
use super::{background, Inner, Runtime};
use crate::reactor::Reactor;
use tokio_reactor;
use tokio_threadpool::Builder as ThreadPoolBuilder;
use tokio_timer::clock::{self, Clock};
use tokio_timer::timer::{self, Timer};
@@ -344,7 +343,7 @@ impl Builder {
.around_worker(move |w| {
let index = w.id().to_usize();
tokio_reactor::with_default(&reactor_handles[index], || {
tokio_net::with_default(&reactor_handles[index], || {
clock::with_default(&clock, || {
timer::with_default(&timer_handles[index], || {
trace::dispatcher::with_default(&dispatch, || {
+1 -1
View File
@@ -173,7 +173,7 @@ impl Runtime {
let trace = &self.inner().trace;
tokio_executor::with_default(&mut self.inner().pool.sender(), || {
tokio_reactor::with_default(bg.reactor(), || {
tokio_net::with_default(bg.reactor(), || {
timer::with_default(bg.timer(), || {
trace::dispatcher::with_default(trace, || {
entered.block_on(future)
+2 -2
View File
@@ -2,7 +2,7 @@
#![warn(rust_2018_idioms)]
#![cfg(feature = "default")]
use tokio_reactor::Reactor;
use tokio_net::Reactor;
use tokio_tcp::TcpListener;
use tokio_test::{assert_ok, assert_pending};
@@ -66,7 +66,7 @@ fn test_drop_on_notify() {
let _enter = tokio_executor::enter().unwrap();
tokio_reactor::with_default(&reactor.handle(), || {
tokio_net::with_default(&reactor.handle(), || {
let waker = waker_ref(&task);
let mut cx = Context::from_waker(&waker);
assert_pending!(task.future.lock().unwrap().as_mut().poll(&mut cx));
+3
View File
@@ -7,11 +7,14 @@ publish = false
[features]
executor-without-current-thread = ["tokio-executor"]
tokio-no-features = ["tokio"]
tokio-with-net = ["tokio/net"]
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
tokio-executor = { path = "../tokio-executor", optional = true }
tokio = { path = "../tokio", optional = true, default-features = false }
[dev-dependencies]
trybuild = "1.0"
+3
View File
@@ -1,2 +1,5 @@
#[cfg(feature = "tokio-executor")]
pub use tokio_executor;
#[cfg(feature = "tokio")]
pub use tokio;
+14 -1
View File
@@ -1,9 +1,22 @@
#[test]
fn features() {
#[cfg(feature = "tokio-with-net")]
#[allow(unused_imports)]
fn tokio_with_net() {
// Reactor is present
use ui_tests::tokio::reactor;
// net is present
use ui_tests::tokio::net;
}
#[test]
fn compile_fail() {
let t = trybuild::TestCases::new();
#[cfg(feature = "executor-without-current-thread")]
t.compile_fail("tests/ui/executor_without_current_thread.rs");
#[cfg(feature = "tokio-no-features")]
t.compile_fail("tests/ui/tokio_without_net_missing_reactor.rs");
drop(t);
}
@@ -0,0 +1,3 @@
use ui_tests::tokio::reactor;
fn main() {}
@@ -0,0 +1,7 @@
error[E0432]: unresolved import `ui_tests::tokio::reactor`
--> $DIR/tokio_without_net_missing_reactor.rs:1:5
|
1 | use ui_tests::tokio::reactor;
| ^^^^^^^^^^^^^^^^^^^^^^^^ no `reactor` in `tokio`
For more information about this error, try `rustc --explain E0432`.