1 | //! Abstractions for asynchronous programming. |
2 | //! |
3 | //! This crate provides a number of core abstractions for writing asynchronous |
4 | //! code: |
5 | //! |
6 | //! - [Futures](crate::future) are single eventual values produced by |
7 | //! asynchronous computations. Some programming languages (e.g. JavaScript) |
8 | //! call this concept "promise". |
9 | //! - [Streams](crate::stream) represent a series of values |
10 | //! produced asynchronously. |
11 | //! - [Sinks](crate::sink) provide support for asynchronous writing of |
12 | //! data. |
13 | //! - [Executors](crate::executor) are responsible for running asynchronous |
14 | //! tasks. |
15 | //! |
16 | //! The crate also contains abstractions for [asynchronous I/O](crate::io) and |
17 | //! [cross-task communication](crate::channel). |
18 | //! |
19 | //! Underlying all of this is the *task system*, which is a form of lightweight |
20 | //! threading. Large asynchronous computations are built up using futures, |
21 | //! streams and sinks, and then spawned as independent tasks that are run to |
22 | //! completion, but *do not block* the thread running them. |
23 | //! |
24 | //! The following example describes how the task system context is built and used |
25 | //! within macros and keywords such as async and await!. |
26 | //! |
27 | //! ```rust |
28 | //! # use futures::channel::mpsc; |
29 | //! # use futures::executor; ///standard executors to provide a context for futures and streams |
30 | //! # use futures::executor::ThreadPool; |
31 | //! # use futures::StreamExt; |
32 | //! # |
33 | //! fn main() { |
34 | //! # { |
35 | //! let pool = ThreadPool::new().expect("Failed to build pool" ); |
36 | //! let (tx, rx) = mpsc::unbounded::<i32>(); |
37 | //! |
38 | //! // Create a future by an async block, where async is responsible for an |
39 | //! // implementation of Future. At this point no executor has been provided |
40 | //! // to this future, so it will not be running. |
41 | //! let fut_values = async { |
42 | //! // Create another async block, again where the Future implementation |
43 | //! // is generated by async. Since this is inside of a parent async block, |
44 | //! // it will be provided with the executor of the parent block when the parent |
45 | //! // block is executed. |
46 | //! // |
47 | //! // This executor chaining is done by Future::poll whose second argument |
48 | //! // is a std::task::Context. This represents our executor, and the Future |
49 | //! // implemented by this async block can be polled using the parent async |
50 | //! // block's executor. |
51 | //! let fut_tx_result = async move { |
52 | //! (0..100).for_each(|v| { |
53 | //! tx.unbounded_send(v).expect("Failed to send" ); |
54 | //! }) |
55 | //! }; |
56 | //! |
57 | //! // Use the provided thread pool to spawn the generated future |
58 | //! // responsible for transmission |
59 | //! pool.spawn_ok(fut_tx_result); |
60 | //! |
61 | //! let fut_values = rx |
62 | //! .map(|v| v * 2) |
63 | //! .collect(); |
64 | //! |
65 | //! // Use the executor provided to this async block to wait for the |
66 | //! // future to complete. |
67 | //! fut_values.await |
68 | //! }; |
69 | //! |
70 | //! // Actually execute the above future, which will invoke Future::poll and |
71 | //! // subsequently chain appropriate Future::poll and methods needing executors |
72 | //! // to drive all futures. Eventually fut_values will be driven to completion. |
73 | //! let values: Vec<i32> = executor::block_on(fut_values); |
74 | //! |
75 | //! println!("Values={:?}" , values); |
76 | //! # } |
77 | //! # std::thread::sleep(std::time::Duration::from_millis(500)); // wait for background threads closed: https://github.com/rust-lang/miri/issues/1371 |
78 | //! } |
79 | //! ``` |
80 | //! |
81 | //! The majority of examples and code snippets in this crate assume that they are |
82 | //! inside an async block as written above. |
83 | |
84 | #![cfg_attr (not(feature = "std" ), no_std)] |
85 | #![warn ( |
86 | missing_debug_implementations, |
87 | missing_docs, |
88 | rust_2018_idioms, |
89 | single_use_lifetimes, |
90 | unreachable_pub |
91 | )] |
92 | #![doc (test( |
93 | no_crate_inject, |
94 | attr( |
95 | deny(warnings, rust_2018_idioms, single_use_lifetimes), |
96 | allow(dead_code, unused_assignments, unused_variables) |
97 | ) |
98 | ))] |
99 | #![cfg_attr (docsrs, feature(doc_cfg))] |
100 | |
101 | #[cfg (all(feature = "bilock" , not(feature = "unstable" )))] |
102 | compile_error!("The `bilock` feature requires the `unstable` feature as an explicit opt-in to unstable features" ); |
103 | |
104 | #[doc (no_inline)] |
105 | pub use futures_core::future::{Future, TryFuture}; |
106 | #[doc (no_inline)] |
107 | pub use futures_util::future::{FutureExt, TryFutureExt}; |
108 | |
109 | #[doc (no_inline)] |
110 | pub use futures_core::stream::{Stream, TryStream}; |
111 | #[doc (no_inline)] |
112 | pub use futures_util::stream::{StreamExt, TryStreamExt}; |
113 | |
114 | #[doc (no_inline)] |
115 | pub use futures_sink::Sink; |
116 | #[doc (no_inline)] |
117 | pub use futures_util::sink::SinkExt; |
118 | |
119 | #[cfg (feature = "std" )] |
120 | #[doc (no_inline)] |
121 | pub use futures_io::{AsyncBufRead, AsyncRead, AsyncSeek, AsyncWrite}; |
122 | #[cfg (feature = "std" )] |
123 | #[doc (no_inline)] |
124 | pub use futures_util::{AsyncBufReadExt, AsyncReadExt, AsyncSeekExt, AsyncWriteExt}; |
125 | |
126 | // Macro reexports |
127 | pub use futures_core::ready; // Readiness propagation |
128 | pub use futures_util::pin_mut; |
129 | #[cfg (feature = "std" )] |
130 | #[cfg (feature = "async-await" )] |
131 | pub use futures_util::select; |
132 | #[cfg (feature = "async-await" )] |
133 | pub use futures_util::{join, pending, poll, select_biased, try_join}; // Async-await |
134 | |
135 | // Module reexports |
136 | #[doc (inline)] |
137 | pub use futures_util::{future, never, sink, stream, task}; |
138 | |
139 | #[cfg (feature = "std" )] |
140 | #[cfg (feature = "async-await" )] |
141 | pub use futures_util::stream_select; |
142 | |
143 | #[cfg (feature = "alloc" )] |
144 | #[doc (inline)] |
145 | pub use futures_channel as channel; |
146 | #[cfg (feature = "alloc" )] |
147 | #[doc (inline)] |
148 | pub use futures_util::lock; |
149 | |
150 | #[cfg (feature = "std" )] |
151 | #[doc (inline)] |
152 | pub use futures_util::io; |
153 | |
154 | #[cfg (feature = "executor" )] |
155 | #[cfg_attr (docsrs, doc(cfg(feature = "executor" )))] |
156 | pub mod executor { |
157 | //! Built-in executors and related tools. |
158 | //! |
159 | //! All asynchronous computation occurs within an executor, which is |
160 | //! capable of spawning futures as tasks. This module provides several |
161 | //! built-in executors, as well as tools for building your own. |
162 | //! |
163 | //! |
164 | //! This module is only available when the `executor` feature of this |
165 | //! library is activated. |
166 | //! |
167 | //! # Using a thread pool (M:N task scheduling) |
168 | //! |
169 | //! Most of the time tasks should be executed on a [thread pool](ThreadPool). |
170 | //! A small set of worker threads can handle a very large set of spawned tasks |
171 | //! (which are much lighter weight than threads). Tasks spawned onto the pool |
172 | //! with the [`spawn_ok`](ThreadPool::spawn_ok) function will run ambiently on |
173 | //! the created threads. |
174 | //! |
175 | //! # Spawning additional tasks |
176 | //! |
177 | //! Tasks can be spawned onto a spawner by calling its [`spawn_obj`] method |
178 | //! directly. In the case of `!Send` futures, [`spawn_local_obj`] can be used |
179 | //! instead. |
180 | //! |
181 | //! # Single-threaded execution |
182 | //! |
183 | //! In addition to thread pools, it's possible to run a task (and the tasks |
184 | //! it spawns) entirely within a single thread via the [`LocalPool`] executor. |
185 | //! Aside from cutting down on synchronization costs, this executor also makes |
186 | //! it possible to spawn non-`Send` tasks, via [`spawn_local_obj`]. The |
187 | //! [`LocalPool`] is best suited for running I/O-bound tasks that do relatively |
188 | //! little work between I/O operations. |
189 | //! |
190 | //! There is also a convenience function [`block_on`] for simply running a |
191 | //! future to completion on the current thread. |
192 | //! |
193 | //! [`spawn_obj`]: https://docs.rs/futures/0.3/futures/task/trait.Spawn.html#tymethod.spawn_obj |
194 | //! [`spawn_local_obj`]: https://docs.rs/futures/0.3/futures/task/trait.LocalSpawn.html#tymethod.spawn_local_obj |
195 | |
196 | pub use futures_executor::{ |
197 | block_on, block_on_stream, enter, BlockingStream, Enter, EnterError, LocalPool, |
198 | LocalSpawner, |
199 | }; |
200 | |
201 | #[cfg (feature = "thread-pool" )] |
202 | #[cfg_attr (docsrs, doc(cfg(feature = "thread-pool" )))] |
203 | pub use futures_executor::{ThreadPool, ThreadPoolBuilder}; |
204 | } |
205 | |
206 | #[cfg (feature = "compat" )] |
207 | #[cfg_attr (docsrs, doc(cfg(feature = "compat" )))] |
208 | pub mod compat { |
209 | //! Interop between `futures` 0.1 and 0.3. |
210 | //! |
211 | //! This module is only available when the `compat` feature of this |
212 | //! library is activated. |
213 | |
214 | pub use futures_util::compat::{ |
215 | Compat, Compat01As03, Compat01As03Sink, CompatSink, Executor01As03, Executor01CompatExt, |
216 | Executor01Future, Future01CompatExt, Sink01CompatExt, Stream01CompatExt, |
217 | }; |
218 | |
219 | #[cfg (feature = "io-compat" )] |
220 | #[cfg_attr (docsrs, doc(cfg(feature = "io-compat" )))] |
221 | pub use futures_util::compat::{AsyncRead01CompatExt, AsyncWrite01CompatExt}; |
222 | } |
223 | |
224 | pub mod prelude { |
225 | //! A "prelude" for crates using the `futures` crate. |
226 | //! |
227 | //! This prelude is similar to the standard library's prelude in that you'll |
228 | //! almost always want to import its entire contents, but unlike the |
229 | //! standard library's prelude you'll have to do so manually: |
230 | //! |
231 | //! ``` |
232 | //! # #[allow (unused_imports)] |
233 | //! use futures::prelude::*; |
234 | //! ``` |
235 | //! |
236 | //! The prelude may grow over time as additional items see ubiquitous use. |
237 | |
238 | pub use crate::future::{self, Future, TryFuture}; |
239 | pub use crate::sink::{self, Sink}; |
240 | pub use crate::stream::{self, Stream, TryStream}; |
241 | |
242 | #[doc (no_inline)] |
243 | #[allow (unreachable_pub)] |
244 | pub use crate::future::{FutureExt as _, TryFutureExt as _}; |
245 | #[doc (no_inline)] |
246 | pub use crate::sink::SinkExt as _; |
247 | #[doc (no_inline)] |
248 | #[allow (unreachable_pub)] |
249 | pub use crate::stream::{StreamExt as _, TryStreamExt as _}; |
250 | |
251 | #[cfg (feature = "std" )] |
252 | pub use crate::io::{AsyncBufRead, AsyncRead, AsyncSeek, AsyncWrite}; |
253 | |
254 | #[cfg (feature = "std" )] |
255 | #[doc (no_inline)] |
256 | #[allow (unreachable_pub)] |
257 | pub use crate::io::{ |
258 | AsyncBufReadExt as _, AsyncReadExt as _, AsyncSeekExt as _, AsyncWriteExt as _, |
259 | }; |
260 | } |
261 | |