mirror of https://github.com/stjepang/smol
Fix compilation errors
This commit is contained in:
parent
a2a2601fc4
commit
1a542a8864
53
Cargo.toml
53
Cargo.toml
|
@ -12,58 +12,47 @@ keywords = ["async", "await", "future", "io", "networking"]
|
|||
categories = ["asynchronous", "concurrency", "network-programming"]
|
||||
readme = "README.md"
|
||||
|
||||
[features]
|
||||
default = []
|
||||
tokio02 = ["tokio"] # Optional feature for compatibility with tokio-based libraries.
|
||||
|
||||
[dependencies]
|
||||
async-channel = "1.1.1"
|
||||
async-executor = "0.1.1"
|
||||
async-io = "0.1.5"
|
||||
blocking = "0.5.0"
|
||||
cfg-if = "0.1.10"
|
||||
easy-parallel = "3.1.0"
|
||||
futures-lite = "0.1.9"
|
||||
num_cpus = "1.13.0"
|
||||
|
||||
[dependencies.tokio]
|
||||
version = "0.2.22"
|
||||
default-features = false
|
||||
features = ["rt-threaded"]
|
||||
optional = true
|
||||
async-channel = "1.4.1"
|
||||
async-executor = "0.2.0"
|
||||
async-fs = "1.1.1"
|
||||
async-io = "0.2.1"
|
||||
async-lock = "2.0.1"
|
||||
async-net = "1.0.0"
|
||||
async-process = "0.1.3"
|
||||
blocking = "0.6.0"
|
||||
futures-lite = "1.0.0"
|
||||
once_cell = "1.4.1"
|
||||
|
||||
[dev-dependencies]
|
||||
anyhow = "1.0.31"
|
||||
async-channel = "1.1.1"
|
||||
anyhow = "1.0.32"
|
||||
async-channel = "1.4.1"
|
||||
async-dup = "1.2.1"
|
||||
async-h1 = "2.1.0"
|
||||
async-h1 = "2.1.2"
|
||||
async-native-tls = "0.3.3"
|
||||
async-net = "0.1.1"
|
||||
async-std = "1.6.2"
|
||||
async-tungstenite = { version = "0.7.1", features = ["async-native-tls"] }
|
||||
async-std = "1.6.3"
|
||||
async-tungstenite = { version = "0.8.0", features = ["async-native-tls"] }
|
||||
base64 = "0.12.3"
|
||||
ctrlc = "3.1.5"
|
||||
ctrlc = "3.1.6"
|
||||
doc-comment = "0.3"
|
||||
futures = "0.3.5"
|
||||
http = "0.2.1"
|
||||
http-types = "2.3.0"
|
||||
http-types = "2.4.0"
|
||||
hyper = { version = "0.13.7", default-features = false, features = ["stream"] }
|
||||
native-tls = "0.2.4"
|
||||
num_cpus = "1.13.0"
|
||||
reqwest = "0.10.6"
|
||||
scraper = "0.12.0"
|
||||
signal-hook = "0.1.16"
|
||||
smol = { path = ".", features = ["tokio02"] }
|
||||
surf = { version = "2.0.0-alpha.4", default-features = false, features = ["h1-client"] }
|
||||
tempfile = "3.1.0"
|
||||
tide = "0.12.0"
|
||||
tungstenite = "0.11.0"
|
||||
tide = "0.13.0"
|
||||
tokio = { version = "0.2.22", default-features = false, features = ["rt-threaded"] }
|
||||
tungstenite = "0.11.1"
|
||||
url = "2.1.1"
|
||||
warp = "0.2.4"
|
||||
|
||||
[target.'cfg(target_os = "linux")'.dev-dependencies]
|
||||
inotify = { version = "0.8.3", default-features = false }
|
||||
nix = "0.17.0"
|
||||
nix = "0.18.0"
|
||||
timerfd = "1.1.1"
|
||||
|
||||
[target.'cfg(windows)'.dev-dependencies]
|
||||
|
|
|
@ -25,7 +25,8 @@ async fn fetch(req: Request) -> Result<Response> {
|
|||
// Connect to the host.
|
||||
let socket_addr = {
|
||||
let host = host.clone();
|
||||
smol::unblock!((host.as_str(), port).to_socket_addrs())?
|
||||
smol::unblock(move || (host.as_str(), port).to_socket_addrs())
|
||||
.await?
|
||||
.next()
|
||||
.context("cannot resolve address")?
|
||||
};
|
||||
|
@ -45,7 +46,7 @@ async fn fetch(req: Request) -> Result<Response> {
|
|||
}
|
||||
|
||||
fn main() -> Result<()> {
|
||||
smol::run(async {
|
||||
smol::block_on(async {
|
||||
// Create a request.
|
||||
let addr = "https://www.rust-lang.org";
|
||||
let req = Request::new(Method::Get, Url::parse(addr)?);
|
||||
|
|
|
@ -18,7 +18,7 @@ use std::net::TcpListener;
|
|||
use anyhow::Result;
|
||||
use async_native_tls::{Identity, TlsAcceptor};
|
||||
use http_types::{Request, Response, StatusCode};
|
||||
use smol::{future, Async, Task};
|
||||
use smol::{future, Async};
|
||||
|
||||
/// Serves a request and returns a response.
|
||||
async fn serve(req: Request) -> http_types::Result<Response> {
|
||||
|
@ -47,7 +47,7 @@ async fn listen(listener: Async<TcpListener>, tls: Option<TlsAcceptor>) -> Resul
|
|||
let task = match &tls {
|
||||
None => {
|
||||
let stream = async_dup::Arc::new(stream);
|
||||
Task::spawn(async move {
|
||||
smol::spawn(async move {
|
||||
if let Err(err) = async_h1::accept(stream, serve).await {
|
||||
println!("Connection error: {:#?}", err);
|
||||
}
|
||||
|
@ -58,7 +58,7 @@ async fn listen(listener: Async<TcpListener>, tls: Option<TlsAcceptor>) -> Resul
|
|||
match tls.accept(stream).await {
|
||||
Ok(stream) => {
|
||||
let stream = async_dup::Arc::new(async_dup::Mutex::new(stream));
|
||||
Task::spawn(async move {
|
||||
smol::spawn(async move {
|
||||
if let Err(err) = async_h1::accept(stream, serve).await {
|
||||
println!("Connection error: {:#?}", err);
|
||||
}
|
||||
|
@ -83,13 +83,13 @@ fn main() -> Result<()> {
|
|||
let tls = TlsAcceptor::from(native_tls::TlsAcceptor::new(identity)?);
|
||||
|
||||
// Start HTTP and HTTPS servers.
|
||||
smol::run(async {
|
||||
smol::block_on(async {
|
||||
let http = listen(Async::<TcpListener>::bind(([127, 0, 0, 1], 8000))?, None);
|
||||
let https = listen(
|
||||
Async::<TcpListener>::bind(([127, 0, 0, 1], 8001))?,
|
||||
Some(tls),
|
||||
);
|
||||
future::try_join(http, https).await?;
|
||||
future::try_zip(http, https).await?;
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ use std::net::TcpStream;
|
|||
use smol::{future, io, Async, Unblock};
|
||||
|
||||
fn main() -> io::Result<()> {
|
||||
smol::run(async {
|
||||
smol::block_on(async {
|
||||
// Connect to the server and create async stdin and stdout.
|
||||
let stream = Async::<TcpStream>::connect(([127, 0, 0, 1], 6000)).await?;
|
||||
let stdin = Unblock::new(std::io::stdin());
|
||||
|
|
|
@ -17,7 +17,7 @@ use std::net::{SocketAddr, TcpListener, TcpStream};
|
|||
|
||||
use async_channel::{bounded, Receiver, Sender};
|
||||
use async_dup::Arc;
|
||||
use smol::{io, prelude::*, Async, Task};
|
||||
use smol::{io, prelude::*, Async};
|
||||
|
||||
/// An event on the chat server.
|
||||
enum Event {
|
||||
|
@ -76,7 +76,7 @@ async fn read_messages(sender: Sender<Event>, client: Arc<Async<TcpStream>>) ->
|
|||
}
|
||||
|
||||
fn main() -> io::Result<()> {
|
||||
smol::run(async {
|
||||
smol::block_on(async {
|
||||
// Create a listener for incoming client connections.
|
||||
let listener = Async::<TcpListener>::bind(([127, 0, 0, 1], 6000))?;
|
||||
|
||||
|
@ -86,7 +86,7 @@ fn main() -> io::Result<()> {
|
|||
|
||||
// Spawn a background task that dispatches events to clients.
|
||||
let (sender, receiver) = bounded(100);
|
||||
Task::spawn(dispatch(receiver)).detach();
|
||||
smol::spawn(dispatch(receiver)).detach();
|
||||
|
||||
loop {
|
||||
// Accept the next connection.
|
||||
|
@ -95,7 +95,7 @@ fn main() -> io::Result<()> {
|
|||
let sender = sender.clone();
|
||||
|
||||
// Spawn a background task reading messages from the client.
|
||||
Task::spawn(async move {
|
||||
smol::spawn(async move {
|
||||
// Client starts with a `Join` event.
|
||||
let _ = sender.send(Event::Join(addr, client.clone())).await;
|
||||
|
||||
|
|
|
@ -6,8 +6,6 @@
|
|||
//! cargo run --example ctrl-c
|
||||
//! ```
|
||||
|
||||
use smol::future;
|
||||
|
||||
fn main() {
|
||||
// Set a handler that sends a message through a channel.
|
||||
let (s, ctrl_c) = async_channel::bounded(100);
|
||||
|
@ -16,7 +14,7 @@ fn main() {
|
|||
};
|
||||
ctrlc::set_handler(handle).unwrap();
|
||||
|
||||
smol::run(async {
|
||||
smol::block_on(async {
|
||||
println!("Waiting for Ctrl-C...");
|
||||
|
||||
// Receive a message that indicates the Ctrl-C signal occurred.
|
||||
|
|
|
@ -10,9 +10,9 @@ use smol::{io, prelude::*, Async, Unblock};
|
|||
use std::net::{TcpStream, ToSocketAddrs};
|
||||
|
||||
fn main() -> io::Result<()> {
|
||||
smol::run(async {
|
||||
smol::block_on(async {
|
||||
// Connect to http://example.com
|
||||
let mut addrs = smol::unblock!(("example.com", 80).to_socket_addrs())?;
|
||||
let mut addrs = smol::unblock(move || ("example.com", 80).to_socket_addrs()).await?;
|
||||
let addr = addrs.next().unwrap();
|
||||
let mut stream = Async::<TcpStream>::connect(addr).await?;
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ use anyhow::{bail, Context as _, Error, Result};
|
|||
use async_native_tls::TlsStream;
|
||||
use http::Uri;
|
||||
use hyper::{Body, Client, Request, Response};
|
||||
use smol::{io, prelude::*, Async, Task};
|
||||
use smol::{io, prelude::*, Async};
|
||||
|
||||
/// Sends a request and fetches the response.
|
||||
async fn fetch(req: Request<Body>) -> Result<Response<Body>> {
|
||||
|
@ -27,7 +27,7 @@ async fn fetch(req: Request<Body>) -> Result<Response<Body>> {
|
|||
}
|
||||
|
||||
fn main() -> Result<()> {
|
||||
smol::run(async {
|
||||
smol::block_on(async {
|
||||
// Create a request.
|
||||
let req = Request::get("https://www.rust-lang.org").body(Body::empty())?;
|
||||
|
||||
|
@ -55,7 +55,7 @@ struct SmolExecutor;
|
|||
|
||||
impl<F: Future + Send + 'static> hyper::rt::Executor<F> for SmolExecutor {
|
||||
fn execute(&self, fut: F) {
|
||||
Task::spawn(async { drop(fut.await) }).detach();
|
||||
smol::spawn(async { drop(fut.await) }).detach();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -81,7 +81,8 @@ impl hyper::service::Service<Uri> for SmolConnector {
|
|||
let socket_addr = {
|
||||
let host = host.to_string();
|
||||
let port = uri.port_u16().unwrap_or(80);
|
||||
smol::unblock!((host.as_str(), port).to_socket_addrs())?
|
||||
smol::unblock(move || (host.as_str(), port).to_socket_addrs())
|
||||
.await?
|
||||
.next()
|
||||
.context("cannot resolve address")?
|
||||
};
|
||||
|
@ -93,7 +94,8 @@ impl hyper::service::Service<Uri> for SmolConnector {
|
|||
let socket_addr = {
|
||||
let host = host.to_string();
|
||||
let port = uri.port_u16().unwrap_or(443);
|
||||
smol::unblock!((host.as_str(), port).to_socket_addrs())?
|
||||
smol::unblock(move || (host.as_str(), port).to_socket_addrs())
|
||||
.await?
|
||||
.next()
|
||||
.context("cannot resolve address")?
|
||||
};
|
||||
|
|
|
@ -21,7 +21,7 @@ use anyhow::{Error, Result};
|
|||
use async_native_tls::{Identity, TlsAcceptor, TlsStream};
|
||||
use hyper::service::{make_service_fn, service_fn};
|
||||
use hyper::{Body, Request, Response, Server};
|
||||
use smol::{future, io, prelude::*, Async, Task};
|
||||
use smol::{future, io, prelude::*, Async};
|
||||
|
||||
/// Serves a request and returns a response.
|
||||
async fn serve(req: Request<Body>, host: String) -> Result<Response<Body>> {
|
||||
|
@ -56,13 +56,13 @@ fn main() -> Result<()> {
|
|||
let tls = TlsAcceptor::from(native_tls::TlsAcceptor::new(identity)?);
|
||||
|
||||
// Start HTTP and HTTPS servers.
|
||||
smol::run(async {
|
||||
smol::block_on(async {
|
||||
let http = listen(Async::<TcpListener>::bind(([127, 0, 0, 1], 8000))?, None);
|
||||
let https = listen(
|
||||
Async::<TcpListener>::bind(([127, 0, 0, 1], 8001))?,
|
||||
Some(tls),
|
||||
);
|
||||
future::try_join(http, https).await?;
|
||||
future::try_zip(http, https).await?;
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
|
@ -73,7 +73,7 @@ struct SmolExecutor;
|
|||
|
||||
impl<F: Future + Send + 'static> hyper::rt::Executor<F> for SmolExecutor {
|
||||
fn execute(&self, fut: F) {
|
||||
Task::spawn(async { drop(fut.await) }).detach();
|
||||
smol::spawn(async { drop(fut.await) }).detach();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@ fn main() -> std::io::Result<()> {
|
|||
}
|
||||
}
|
||||
|
||||
smol::run(async {
|
||||
smol::block_on(async {
|
||||
// Watch events in the current directory.
|
||||
let mut inotify = Async::new(Inotify::init()?)?;
|
||||
inotify.get_mut().add_watch(".", WatchMask::ALL_EVENTS)?;
|
||||
|
|
|
@ -35,7 +35,7 @@ fn main() -> std::io::Result<()> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
smol::run(async {
|
||||
smol::block_on(async {
|
||||
let start = Instant::now();
|
||||
println!("Sleeping...");
|
||||
|
||||
|
|
|
@ -1,48 +0,0 @@
|
|||
//! Demonstrates how to use `async-std`, `tokio`, `surf`, and `request`.
|
||||
//!
|
||||
//! For compatibility with tokio-based libraries, enable the `tokio02` feature flag:
|
||||
//!
|
||||
//! ```toml
|
||||
//! [dependencies]
|
||||
//! smol = { version = "0.3", features = ["tokio02"] }
|
||||
//! ```
|
||||
//!
|
||||
//! Run with:
|
||||
//!
|
||||
//! ```
|
||||
//! cargo run --example other-runtimes
|
||||
//! ```
|
||||
|
||||
use std::time::{Duration, Instant};
|
||||
|
||||
use anyhow::{Error, Result};
|
||||
|
||||
fn main() -> Result<()> {
|
||||
smol::run(async {
|
||||
// Sleep using async-std.
|
||||
let start = Instant::now();
|
||||
println!("Sleeping using async-std...");
|
||||
async_std::task::sleep(Duration::from_secs(1)).await;
|
||||
println!("Woke up after {:?}", start.elapsed());
|
||||
|
||||
// Sleep using tokio (the `tokio02` feature must be enabled).
|
||||
let start = Instant::now();
|
||||
println!("Sleeping using tokio...");
|
||||
tokio::time::delay_for(Duration::from_secs(1)).await;
|
||||
println!("Woke up after {:?}", start.elapsed());
|
||||
|
||||
// Make a GET request using surf.
|
||||
let body = surf::get("https://www.rust-lang.org")
|
||||
.recv_string()
|
||||
.await
|
||||
.map_err(Error::msg)?;
|
||||
println!("Body from surf: {:?}", body);
|
||||
|
||||
// Make a GET request using reqwest (the `tokio02` feature must be enabled).
|
||||
let resp = reqwest::get("https://www.rust-lang.org").await?;
|
||||
let body = resp.text().await?;
|
||||
println!("Body from reqwest: {:?}", body);
|
||||
|
||||
Ok(())
|
||||
})
|
||||
}
|
|
@ -33,7 +33,8 @@ async fn fetch(addr: &str) -> Result<Vec<u8>> {
|
|||
// Connect to the host.
|
||||
let socket_addr = {
|
||||
let host = host.clone();
|
||||
smol::unblock!((host.as_str(), port).to_socket_addrs())?
|
||||
smol::unblock(move || (host.as_str(), port).to_socket_addrs())
|
||||
.await?
|
||||
.next()
|
||||
.context("cannot resolve address")?
|
||||
};
|
||||
|
@ -59,7 +60,7 @@ async fn fetch(addr: &str) -> Result<Vec<u8>> {
|
|||
}
|
||||
|
||||
fn main() -> Result<()> {
|
||||
smol::run(async {
|
||||
smol::block_on(async {
|
||||
let addr = "https://www.rust-lang.org";
|
||||
let resp = fetch(addr).await?;
|
||||
println!("{}", String::from_utf8_lossy(&resp));
|
||||
|
|
|
@ -17,7 +17,7 @@ use std::net::{TcpListener, TcpStream};
|
|||
|
||||
use anyhow::Result;
|
||||
use async_native_tls::{Identity, TlsAcceptor};
|
||||
use smol::{future, prelude::*, Async, Task};
|
||||
use smol::{future, prelude::*, Async};
|
||||
|
||||
const RESPONSE: &[u8] = br#"
|
||||
HTTP/1.1 200 OK
|
||||
|
@ -65,7 +65,7 @@ async fn listen(listener: Async<TcpListener>, tls: Option<TlsAcceptor>) -> Resul
|
|||
let tls = tls.clone();
|
||||
|
||||
// Spawn a background task serving this connection.
|
||||
Task::spawn(async move {
|
||||
smol::spawn(async move {
|
||||
if let Err(err) = serve(stream, tls).await {
|
||||
println!("Connection error: {:#?}", err);
|
||||
}
|
||||
|
@ -80,13 +80,13 @@ fn main() -> Result<()> {
|
|||
let tls = TlsAcceptor::from(native_tls::TlsAcceptor::new(identity)?);
|
||||
|
||||
// Start HTTP and HTTPS servers.
|
||||
smol::run(async {
|
||||
smol::block_on(async {
|
||||
let http = listen(Async::<TcpListener>::bind(([127, 0, 0, 1], 8000))?, None);
|
||||
let https = listen(
|
||||
Async::<TcpListener>::bind(([127, 0, 0, 1], 8001))?,
|
||||
Some(tls),
|
||||
);
|
||||
future::try_join(http, https).await?;
|
||||
future::try_zip(http, https).await?;
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ use std::net::TcpStream;
|
|||
use smol::{future, io, Async, Unblock};
|
||||
|
||||
fn main() -> io::Result<()> {
|
||||
smol::run(async {
|
||||
smol::block_on(async {
|
||||
// Create async stdin and stdout handles.
|
||||
let stdin = Unblock::new(std::io::stdin());
|
||||
let mut stdout = Unblock::new(std::io::stdout());
|
||||
|
@ -28,7 +28,7 @@ fn main() -> io::Result<()> {
|
|||
println!("Type a message and hit enter!\n");
|
||||
|
||||
// Pipe messages from stdin to the server and pipe messages from the server to stdout.
|
||||
future::try_join(
|
||||
future::try_zip(
|
||||
io::copy(stdin, &mut &stream),
|
||||
io::copy(&stream, &mut stdout),
|
||||
)
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
|
||||
use std::net::{TcpListener, TcpStream};
|
||||
|
||||
use smol::{io, Async, Task};
|
||||
use smol::{io, Async};
|
||||
|
||||
/// Echoes messages from the client back to it.
|
||||
async fn echo(stream: Async<TcpStream>) -> io::Result<()> {
|
||||
|
@ -23,7 +23,7 @@ async fn echo(stream: Async<TcpStream>) -> io::Result<()> {
|
|||
}
|
||||
|
||||
fn main() -> io::Result<()> {
|
||||
smol::run(async {
|
||||
smol::block_on(async {
|
||||
// Create a listener.
|
||||
let listener = Async::<TcpListener>::bind(([127, 0, 0, 1], 7000))?;
|
||||
println!("Listening on {}", listener.get_ref().local_addr()?);
|
||||
|
@ -35,7 +35,7 @@ fn main() -> io::Result<()> {
|
|||
println!("Accepted client: {}", peer_addr);
|
||||
|
||||
// Spawn a task that echoes messages from the client back to it.
|
||||
Task::spawn(echo(stream)).detach();
|
||||
smol::spawn(echo(stream)).detach();
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
@ -24,7 +24,7 @@ fn main() -> Result<()> {
|
|||
builder.add_root_certificate(Certificate::from_pem(include_bytes!("certificate.pem"))?);
|
||||
let tls = TlsConnector::from(builder);
|
||||
|
||||
smol::run(async {
|
||||
smol::block_on(async {
|
||||
// Create async stdin and stdout handles.
|
||||
let stdin = Unblock::new(std::io::stdin());
|
||||
let mut stdout = Unblock::new(std::io::stdout());
|
||||
|
@ -37,7 +37,7 @@ fn main() -> Result<()> {
|
|||
|
||||
// Pipe messages from stdin to the server and pipe messages from the server to stdout.
|
||||
let stream = async_dup::Mutex::new(stream);
|
||||
future::try_join(
|
||||
future::try_zip(
|
||||
io::copy(stdin, &mut &stream),
|
||||
io::copy(&stream, &mut stdout),
|
||||
)
|
||||
|
|
|
@ -16,7 +16,7 @@ use std::net::{TcpListener, TcpStream};
|
|||
|
||||
use anyhow::Result;
|
||||
use async_native_tls::{Identity, TlsAcceptor, TlsStream};
|
||||
use smol::{io, Async, Task};
|
||||
use smol::{io, Async};
|
||||
|
||||
/// Echoes messages from the client back to it.
|
||||
async fn echo(stream: TlsStream<Async<TcpStream>>) -> Result<()> {
|
||||
|
@ -30,7 +30,7 @@ fn main() -> Result<()> {
|
|||
let identity = Identity::from_pkcs12(include_bytes!("identity.pfx"), "password")?;
|
||||
let tls = TlsAcceptor::from(native_tls::TlsAcceptor::new(identity)?);
|
||||
|
||||
smol::run(async {
|
||||
smol::block_on(async {
|
||||
// Create a listener.
|
||||
let listener = Async::<TcpListener>::bind(([127, 0, 0, 1], 7001))?;
|
||||
println!("Listening on {}", listener.get_ref().local_addr()?);
|
||||
|
@ -46,7 +46,7 @@ fn main() -> Result<()> {
|
|||
);
|
||||
|
||||
// Spawn a task that echoes messages from the client back to it.
|
||||
Task::spawn(echo(stream)).detach();
|
||||
smol::spawn(echo(stream)).detach();
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ fn main() -> std::io::Result<()> {
|
|||
|
||||
use smol::{prelude::*, Async};
|
||||
|
||||
smol::run(async {
|
||||
smol::block_on(async {
|
||||
// Create a Unix stream that receives a byte on each signal occurrence.
|
||||
let (a, mut b) = Async::<UnixStream>::pair()?;
|
||||
signal_hook::pipe::register(signal_hook::SIGINT, a)?;
|
||||
|
|
|
@ -11,7 +11,6 @@ use std::collections::{HashSet, VecDeque};
|
|||
use anyhow::Result;
|
||||
use async_channel::{bounded, Sender};
|
||||
use scraper::{Html, Selector};
|
||||
use smol::Task;
|
||||
|
||||
const ROOT: &str = "https://www.rust-lang.org";
|
||||
|
||||
|
@ -34,7 +33,7 @@ fn links(body: String) -> Vec<String> {
|
|||
}
|
||||
|
||||
fn main() -> Result<()> {
|
||||
smol::run(async {
|
||||
smol::block_on(async {
|
||||
let mut seen = HashSet::new();
|
||||
let mut queue = VecDeque::new();
|
||||
seen.insert(ROOT.to_string());
|
||||
|
@ -53,7 +52,7 @@ fn main() -> Result<()> {
|
|||
Some(url) => {
|
||||
println!("{}", url);
|
||||
tasks += 1;
|
||||
Task::spawn(fetch(url, s.clone())).detach();
|
||||
smol::spawn(fetch(url, s.clone())).detach();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,7 +35,8 @@ async fn connect(addr: &str, tls: TlsConnector) -> Result<(WsStream, Response)>
|
|||
// Resolve the address.
|
||||
let socket_addr = {
|
||||
let host = host.clone();
|
||||
smol::unblock!((host.as_str(), port).to_socket_addrs())?
|
||||
smol::unblock(move || (host.as_str(), port).to_socket_addrs())
|
||||
.await?
|
||||
.next()
|
||||
.context("cannot resolve address")?
|
||||
};
|
||||
|
@ -64,7 +65,7 @@ fn main() -> Result<()> {
|
|||
builder.add_root_certificate(Certificate::from_pem(include_bytes!("certificate.pem"))?);
|
||||
let tls = TlsConnector::from(builder);
|
||||
|
||||
smol::run(async {
|
||||
smol::block_on(async {
|
||||
// Connect to the server.
|
||||
let (mut stream, resp) = connect("wss://127.0.0.1:9001", tls).await?;
|
||||
dbg!(resp);
|
||||
|
|
|
@ -20,7 +20,7 @@ use anyhow::{Context as _, Result};
|
|||
use async_native_tls::{Identity, TlsAcceptor, TlsStream};
|
||||
use async_tungstenite::WebSocketStream;
|
||||
use futures::sink::{Sink, SinkExt};
|
||||
use smol::{future, prelude::*, Async, Task};
|
||||
use smol::{future, prelude::*, Async};
|
||||
use tungstenite::Message;
|
||||
|
||||
/// Echoes messages from the client back to it.
|
||||
|
@ -46,13 +46,13 @@ async fn listen(listener: Async<TcpListener>, tls: Option<TlsAcceptor>) -> Resul
|
|||
match &tls {
|
||||
None => {
|
||||
let stream = WsStream::Plain(async_tungstenite::accept_async(stream).await?);
|
||||
Task::spawn(echo(stream)).detach();
|
||||
smol::spawn(echo(stream)).detach();
|
||||
}
|
||||
Some(tls) => {
|
||||
// In case of WSS, establish a secure TLS connection first.
|
||||
let stream = tls.accept(stream).await?;
|
||||
let stream = WsStream::Tls(async_tungstenite::accept_async(stream).await?);
|
||||
Task::spawn(echo(stream)).detach();
|
||||
smol::spawn(echo(stream)).detach();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -64,13 +64,13 @@ fn main() -> Result<()> {
|
|||
let tls = TlsAcceptor::from(native_tls::TlsAcceptor::new(identity)?);
|
||||
|
||||
// Start WS and WSS servers.
|
||||
smol::run(async {
|
||||
smol::block_on(async {
|
||||
let ws = listen(Async::<TcpListener>::bind(([127, 0, 0, 1], 9000))?, None);
|
||||
let wss = listen(
|
||||
Async::<TcpListener>::bind(([127, 0, 0, 1], 9001))?,
|
||||
Some(tls),
|
||||
);
|
||||
future::try_join(ws, wss).await?;
|
||||
future::try_zip(ws, wss).await?;
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
fn main() -> std::io::Result<()> {
|
||||
use std::path::PathBuf;
|
||||
|
||||
use smol::{io, prelude::*, Async, Task, Unblock};
|
||||
use smol::{io, prelude::*, Async, Unblock};
|
||||
use tempfile::tempdir;
|
||||
use uds_windows::{UnixListener, UnixStream};
|
||||
|
||||
|
@ -28,13 +28,13 @@ fn main() -> std::io::Result<()> {
|
|||
let dir = tempdir()?;
|
||||
let path = dir.path().join("socket");
|
||||
|
||||
smol::run(async {
|
||||
smol::block_on(async {
|
||||
// Create a listener.
|
||||
let listener = Async::new(UnixListener::bind(&path)?)?;
|
||||
println!("Listening on {:?}", listener.get_ref().local_addr()?);
|
||||
|
||||
// Spawn a client task.
|
||||
let task = Task::spawn(client(path));
|
||||
let task = smol::spawn(client(path));
|
||||
|
||||
// Accept the client.
|
||||
let (stream, _) = listener.read_with(|l| l.accept()).await?;
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
version = 'Two'
|
188
src/lib.rs
188
src/lib.rs
|
@ -5,12 +5,11 @@
|
|||
//! Connect to an HTTP website, make a GET request, and pipe the response to the standard output:
|
||||
//!
|
||||
//! ```
|
||||
//! use async_net::TcpStream;
|
||||
//! use smol::{io, prelude::*, Unblock};
|
||||
//! use smol::{io, net, prelude::*, Unblock};
|
||||
//!
|
||||
//! fn main() -> io::Result<()> {
|
||||
//! smol::run(async {
|
||||
//! let mut stream = TcpStream::connect("example.com:80").await?;
|
||||
//! smol::block_on(async {
|
||||
//! let mut stream = net::TcpStream::connect("example.com:80").await?;
|
||||
//! let req = b"GET / HTTP/1.1\r\nHost: example.com\r\nConnection: close\r\n\r\n";
|
||||
//! stream.write_all(req).await?;
|
||||
//!
|
||||
|
@ -21,32 +20,14 @@
|
|||
//! }
|
||||
//! ```
|
||||
//!
|
||||
//! This example uses [`async-net`] for networking, but you can also use the primitive [`Async`]
|
||||
//! type. See the [full code][get-request].
|
||||
//! This example uses the [`net`] module for networking, but you can also use the primitive
|
||||
//! [`Async`] type. See the [full code][get-request].
|
||||
//!
|
||||
//! Look inside the [examples] directory for more.
|
||||
//!
|
||||
//! [`async-net`]: https://docs.rs/async-net
|
||||
//! [examples]: https://github.com/stjepang/smol/tree/master/examples
|
||||
//! [get-request]: https://github.com/stjepang/smol/blob/master/examples/get-request.rs
|
||||
//!
|
||||
//! # Compatibility
|
||||
//!
|
||||
//! All async libraries work with smol out of the box.
|
||||
//!
|
||||
//! The only exception is [tokio], which is traditionally incompatible with [futures] and crashes
|
||||
//! when called from other executors. Fortunately, there are ways around it.
|
||||
//!
|
||||
//! Enable the `tokio02` feature flag and [`smol::run()`][`crate::run()`] will create a minimal
|
||||
//! tokio runtime for its libraries:
|
||||
//!
|
||||
//! ```toml
|
||||
//! [dependencies]
|
||||
//! smol = { version = "0.3", features = ["tokio02"] }
|
||||
//! ```
|
||||
//!
|
||||
//! [tokio]: https://docs.rs/tokio
|
||||
//! [futures]: https://docs.rs/futures
|
||||
|
||||
#![forbid(unsafe_code)]
|
||||
#![warn(missing_docs, missing_debug_implementations, rust_2018_idioms)]
|
||||
|
@ -54,31 +35,38 @@
|
|||
#[cfg(doctest)]
|
||||
doc_comment::doctest!("../README.md");
|
||||
|
||||
use std::env;
|
||||
use std::future::Future;
|
||||
use std::panic::catch_unwind;
|
||||
use std::thread;
|
||||
|
||||
use async_executor::{Executor, LocalExecutor};
|
||||
use cfg_if::cfg_if;
|
||||
use easy_parallel::Parallel;
|
||||
use once_cell::sync::Lazy;
|
||||
|
||||
#[doc(inline)]
|
||||
pub use {
|
||||
async_executor::Task,
|
||||
async_io::Async,
|
||||
async_io::Timer,
|
||||
async_executor::{Executor, LocalExecutor, Task},
|
||||
async_io::{block_on, Async, Timer},
|
||||
blocking::{unblock, Unblock},
|
||||
futures_lite::{future, io, stream},
|
||||
futures_lite::{pin, ready},
|
||||
};
|
||||
|
||||
/// Async traits and their extensions.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use smol::prelude::*;
|
||||
/// ```
|
||||
// TODO: Mutex::lock_arc() -> ArcMutexGuard, also Mutex::try_lock_arc()
|
||||
#[doc(inline)]
|
||||
pub use {
|
||||
async_channel as channel, async_fs as fs, async_lock as lock, async_net as net,
|
||||
async_process as process,
|
||||
};
|
||||
|
||||
pub mod prelude {
|
||||
//! Traits [`Future`], [`AsyncBufRead`], [`AsyncRead`], [`AsyncSeek`], [`AsyncWrite`], and
|
||||
//! their extensions.
|
||||
//!
|
||||
//! # Examples
|
||||
//!
|
||||
//! ```
|
||||
//! use smol::prelude::*;
|
||||
//! ```
|
||||
|
||||
#[doc(no_inline)]
|
||||
pub use futures_lite::{
|
||||
future::{Future, FutureExt},
|
||||
|
@ -90,111 +78,35 @@ pub mod prelude {
|
|||
};
|
||||
}
|
||||
|
||||
/// Starts a thread-local executor and then runs the future.
|
||||
/// Spawns a task onto the single-threaded global executor.
|
||||
///
|
||||
/// There is a single-threaded global executor that gets lazily initialized on first use. It is
|
||||
/// advisable to use it in tests or small programs, but it is otherwise a better idea to define
|
||||
/// your own [`Executor`]s.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use smol::Task;
|
||||
/// let task = smol::spawn(async {
|
||||
/// 1 + 2
|
||||
/// });
|
||||
///
|
||||
/// smol::block_on(async {
|
||||
/// let task = Task::local(async {
|
||||
/// println!("Hello world");
|
||||
/// });
|
||||
/// task.await;
|
||||
/// })
|
||||
/// assert_eq!(task.await, 3);
|
||||
/// });
|
||||
/// ```
|
||||
pub fn block_on<T>(future: impl Future<Output = T>) -> T {
|
||||
let local_ex = LocalExecutor::new();
|
||||
|
||||
cfg_if! {
|
||||
if #[cfg(not(feature = "tokio02"))] {
|
||||
local_ex.run(future)
|
||||
} else {
|
||||
// A minimal tokio runtime to support libraries depending on it.
|
||||
let mut rt = tokio::runtime::Builder::new()
|
||||
.enable_all()
|
||||
.basic_scheduler()
|
||||
.build()
|
||||
.expect("cannot start tokio runtime");
|
||||
let handle = rt.handle().clone();
|
||||
|
||||
// A channel that coordinates shutdown when the main future completes.
|
||||
let (trigger, shutdown) = async_channel::unbounded::<()>();
|
||||
let future = async move {
|
||||
let _trigger = trigger; // Dropped at the end of this async block.
|
||||
future.await
|
||||
};
|
||||
|
||||
Parallel::new()
|
||||
.add(|| rt.block_on(shutdown.recv()))
|
||||
.finish(|| handle.enter(|| local_ex.run(future)))
|
||||
.1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Starts a thread-local and a multi-threaded executor and then runs the future.
|
||||
///
|
||||
/// This function runs two executors at the same time:
|
||||
///
|
||||
/// 1. The current thread runs a [`LocalExecutor`] and the main `future` on it.
|
||||
/// 2. A thread pool runs an [`Executor`] until the main `future` completes.
|
||||
///
|
||||
/// The number of spawned threads matches the number of logical CPU cores on the system, but it can
|
||||
/// be overriden by setting the `SMOL_THREADS` environment variable.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use smol::Task;
|
||||
///
|
||||
/// smol::run(async {
|
||||
/// let task = Task::spawn(async {
|
||||
/// println!("Hello world");
|
||||
/// });
|
||||
/// task.await;
|
||||
/// })
|
||||
/// ```
|
||||
pub fn run<T>(future: impl Future<Output = T>) -> T {
|
||||
// A channel that coordinates shutdown when the main future completes.
|
||||
let (trigger, shutdown) = async_channel::unbounded::<()>();
|
||||
let future = async move {
|
||||
let _trigger = trigger; // Dropped at the end of this async block.
|
||||
future.await
|
||||
};
|
||||
|
||||
let num_threads = {
|
||||
// Parse SMOL_THREADS or use the number of CPU cores on the system.
|
||||
env::var("SMOL_THREADS")
|
||||
.ok()
|
||||
.and_then(|s| s.parse().ok())
|
||||
.unwrap_or_else(|| num_cpus::get())
|
||||
};
|
||||
|
||||
let ex = Executor::new();
|
||||
let local_ex = LocalExecutor::new();
|
||||
|
||||
cfg_if! {
|
||||
if #[cfg(not(feature = "tokio02"))] {
|
||||
Parallel::new()
|
||||
.each(0..num_threads, |_| ex.run(shutdown.recv()))
|
||||
.finish(|| ex.enter(|| local_ex.run(future)))
|
||||
.1
|
||||
} else {
|
||||
// A minimal tokio runtime to support libraries depending on it.
|
||||
let mut rt = tokio::runtime::Builder::new()
|
||||
.enable_all()
|
||||
.basic_scheduler()
|
||||
.build()
|
||||
.expect("cannot start tokio runtime");
|
||||
let handle = rt.handle().clone();
|
||||
|
||||
Parallel::new()
|
||||
.add(|| ex.enter(|| rt.block_on(shutdown.recv())))
|
||||
.each(0..num_threads, |_| handle.enter(|| ex.run(shutdown.recv())))
|
||||
.finish(|| handle.enter(|| ex.enter(|| local_ex.run(future))))
|
||||
.1
|
||||
}
|
||||
}
|
||||
pub fn spawn<T: Send + 'static>(future: impl Future<Output = T> + Send + 'static) -> Task<T> {
|
||||
static GLOBAL: Lazy<Executor> = Lazy::new(|| {
|
||||
thread::Builder::new()
|
||||
.name("smol".to_string())
|
||||
.spawn(|| {
|
||||
loop {
|
||||
let _ =
|
||||
catch_unwind(|| async_io::block_on(GLOBAL.run(future::pending::<()>())));
|
||||
}
|
||||
})
|
||||
.unwrap();
|
||||
Executor::new()
|
||||
});
|
||||
GLOBAL.spawn(future)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue