1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
//! A Rust async runtime abstraction library.
//!
//! Provides a unified [`Runtime`] type and [`traits`] such as [`Executor`](traits::Executor),
//! [`Reactor`](traits::Reactor), and [`AsyncToSocketAddrs`](traits::AsyncToSocketAddrs) that
//! abstract over Tokio, smol, and async-global-executor. Features enable implementations and may
//! be combined. Applications choose a runtime when constructing [`Runtime`]; library crates can
//! use generic trait bounds to remain runtime-agnostic.
//!
//! # Feature flags
//!
//! | Flag | Notes |
//! |------|-------|
//! | `tokio` *(default)* | Tokio runtime |
//! | `smol` | smol executor |
//! | `async-global-executor` | Executor; combine with `async-io` for `AGERuntime` |
//! | `async-io` | async-io reactor (required by `smol`) |
//! | `hickory-dns` | Hickory DNS resolver (tokio only) |
//!
//! [`NoopRuntime`] is always available without a feature flag.
//!
//! An owned Tokio runtime uses nonblocking shutdown when its final owner is dropped while a Tokio
//! handle is current. This includes a plain `Handle::enter()` scope, so `spawn_blocking` work can
//! continue after the drop returns. Await work that must finish before dropping the final owner.
//! On a plain thread, leave the `Handle::enter()` scope first or call
//! `TokioRuntime::shutdown_blocking()` to wait. The method returns the runtime if another clone
//! still owns it or it is called from a Tokio task, including a `spawn_blocking` task. Call it
//! from an ordinary thread, not a runtime worker or an active async executor.
//!
//! # Example
//!
//! ```rust
//! # #[cfg(feature="tokio")]
//! # {
//! use async_rs::{Runtime, TokioRuntime, traits::*};
//! use std::{io, time::Duration};
//!
//! async fn get_a(rt: &TokioRuntime) -> io::Result<u32> {
//! rt.spawn_blocking(|| Ok(12)).await
//! }
//!
//! async fn get_b(rt: &TokioRuntime) -> io::Result<u32> {
//! rt.spawn(async { Ok(30) }).await
//! }
//!
//! async fn tokio_main(rt: &TokioRuntime) -> io::Result<()> {
//! let a = get_a(rt).await?;
//! let b = get_b(rt).await?;
//! rt.sleep(Duration::from_millis(500)).await;
//! assert_eq!(a + b, 42);
//! Ok(())
//! }
//!
//! fn main() -> io::Result<()> {
//! let rt = Runtime::tokio()?;
//! rt.block_on(tokio_main(&rt))
//! }
//! # }
//! ```
//!
//! Note that the `io::Result` above is the *task's own* output: awaiting a
//! [`Task`](util::Task) leaves no room to report that the task itself failed,
//! so a task which panicked resumes its panic in the awaiting task, and
//! awaiting one which was canceled, or whose runtime went away, panics too.
pub use *;
pub use *;