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 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322
//! # async_runtime //! //! [![standard-readme compliant](https://img.shields.io/badge/readme%20style-standard-brightgreen.svg?style=flat-square)](https://github.com/RichardLitt/standard-readme) //! [![Build Status](https://api.travis-ci.org/najamelan/async_runtime.svg?branch=master)](https://travis-ci.org/najamelan/async_runtime) //! [![Docs](https://docs.rs/naja_async_runtime/badge.svg)](https://docs.rs/naja_async_runtime) //! ![crates.io](https://img.shields.io/crates/v/naja_async_runtime.svg) //! //! //! > A lightweight runtime for global spawning of futures. //! //! The purpose of `async_runtime` is to make it convenient to spawn and run futures. //! It allows library authors to call [`rt::spawn( future );`](rt::spawn) rather than having to take a `T: Executor`, //! yet let client code decide what kind of executor is used. Currently the choice is between //! futures 0.3 `LocalPool` and the [juliex](https://github.com/withoutboats/juliex) threadpool. //! Other implementations might be added later. //! //! Differences with the [runtime](https://github.com/rustasync/runtime) crate: //! //! - no need to box futures to spawn them, but you can spawn boxed futures just the same //! - client code can decide that the executor for the thread is a LocalPool (can be a serious performance benefit sometimes) //! - the executor is not a trait object, so you can't just implement a different one without //! patching this crate. I have not yet found the use for this, and tokio futures and streams //! run just fine with the compatibility layer from futures 0.3. If the provided executors are //! not sufficient, please file an issue or a pull request. //! //! Both crates work on WASM. //! //! When not on WASM, the default executor is the juliex threadpool (unless you use `default-features = false`). //! This is because the executor is set per thread and when tasks run on a threadpool thread and they spawn, //! they will automatically spawn on the threadpool. This alleviates the need for initialization code on the threadpool //! threads. This means that you have to call [`rt::init`] if you want the `LocalPool` (or disable the default features). //! //! On WASM, the default executor is also a threadpool, even though that's impossible (wasm does not have threads right now). //! It's recommended to use `default-features = false` on wasm to disable the dependency on juliex. //! This will change the default executor to be the local pool. This might seem like an odd API design, //! but WASM will have threads in the future, so I prefered keeping the API future proof and consistent with other targets. //! Another consistency choice is that `spawn` and `spawn_local` return Result, even though currently on wasm //! they cannot fail. //! //! There isn't currently a separate api documentation for WASM and docs.rs will not show modules included only //! when the target is WASM. However, the use of the library is identical, so I have chosen not to set up a separate //! documentation. You can check the wasm example in the //! [examples directory of the repository](https://github.com/najamelan/async_runtime/tree/master/examples), as //! well as the integration tests. You can also clone the repository and run: //! `cargo doc --open --target wasm32-unknown-unknown` or read the source code. //! //! //! ## Table of Contents //! //! - [Install](#install) //! - [Features](#features) //! - [Dependencies](#dependencies) //! - [Usage](#usage) //! - [WASM](#wasm) //! - [API](#api) //! - [Contributing](#contributing) //! - [Code of Conduct](#code-of-conduct) //! - [License](#license) //! //! //! ## Install //! With [cargo add](https://github.com/killercup/cargo-edit): //! `cargo add async_runtime` //! //! With [cargo yaml](https://gitlab.com/storedbox/cargo-yaml): //! ```yaml //! dependencies: //! //! async_runtime: { version: ^0.1, package: naja_async_runtime } //! ``` //! //! With raw Cargo.toml //! ```toml //! [dependencies] //! //! async_runtime = { version = "^0.1", package = "naja_async_runtime" } //! ``` //! //! ### Features //! //! There is one feature: `juliex`. It's on by default and you can turn it off if you only want the localpool. On wasm, turn it off as it's not being used. See the [Dependencies section](#dependencies). //! //! ### Dependencies //! //! This crate has few dependiencies. Cargo will automatically handle it's dependencies for you, except: //! //! - `juliex` is optional. Add the dependency with `default-features = false` to disable. On wasm you should also //! do this as it won't be used: //! //! ```toml //! [dependencies] //! //! async_runtime = { version = "^0.1", default-features = false, package = "naja_async_runtime" } //! ``` //! //! Other dependencies: //! //! ```yaml //! failure : ^0.1 //! futures-preview : { version: ^0.3.0-alpha.16, features: [ std, compat, nightly ], default-features: false } //! log : ^0.4 //! once_cell : ^0.1 //! juliex : { version: 0.3.0-alpha.6, optional: true } //! ``` //! //! ## Usage //! //! Please have a look in the [examples directory of the repository](https://github.com/najamelan/async_runtime/tree/master/examples). //! //! ```rust //! # #![ feature( async_await ) ] //! # //! # // unfortunately we can't rename the crate itself in Cargo.yml. //! # // //! # use naja_async_runtime as async_runtime; //! # //! use //! { //! async_runtime :: { * } , //! }; //! //! // in library code: //! // //! fn do_something_in_parallel() -> Result<(), RtErr> //! { //! rt::spawn( async //! { //! println!( "I'm running in async context" ); //! }) //! } //! //! // In client code we might decide that this runs in a LocalPool, instead of a threadpool: //! // //! fn main() //! { //! // This only fails if you initialize twice. Therefor library code should not do this //! // unless the library is creating the threads. //! // //! rt::init( RtConfig::Local ).expect( "executor init" ); //! //! // Please look at the documentation for rt::spawn for the possible errors here. //! // //! do_something_in_parallel().expect( "Spawn futures" ); //! //! // On a threadpool, futures are polled immediately, but since here we only have one thread, //! // first we spawn our topmost tasks and then we have to tell the runtime that it's time to //! // start polling them. This will block the thread until all futures are finished. //! // //! rt::run(); //! } //! //! ``` //! //! ```rust //! // In this example we run a bunch of tasks in parallel. To verify that //! // they run on different threads we make them all sleep for a second and //! // measure the time passed when they finish. //! //! #![ feature( async_await, duration_constants ) ] //! //! # // unfortunately we can't rename the crate itself in Cargo.yml. //! # // //! # use naja_async_runtime as async_runtime; //! # //! use //! { //! async_runtime :: { * } , //! std :: { time::{ Duration, Instant }, thread::sleep } , //! futures :: { future::{ FutureExt, join_all } } , //! }; //! //! fn main() //! { //! let program = async //! { //! let start = Instant::now(); //! let mut tasks = Vec::new(); //! //! for i in 0..8 //! { //! // There isn't currently a convenient way to run tasks on a threadpool //! // until all tasks have finished, or until some shutdown signal is given. //! // //! // This is one of the ways tasks can synchronize and wait on each other. //! // Another way is to wait on channels. //! // //! let (fut, handle) = async move //! { //! sleep( Duration::SECOND ); //! //! println! //! ( //! "Time elapsed at task {} end: {} second(s).", //! i, start.elapsed().as_secs() //! ); //! //! }.remote_handle(); //! //! //! // If the juliex feature is enabled, RtConfig::Pool becomes the default executor, so we don't //! // have to call rt::init. //! // //! rt::spawn( fut ).expect( "spawn task" ); //! tasks.push( handle ); //! } //! //! join_all( tasks ).await; //! }; //! //! futures::executor::block_on( program ); //! } //! ``` //! //! ### Wasm //! //! Note that it's best to turn of default-features in your Cargo.toml to avoid loading `juliex` //! which isn't used on wasm. //! ```toml //! [dependencies] //! //! async_runtime = { version = "^0.1", default-features = false, package = "naja_async_runtime" } //! ``` //! //! To use the crate in wasm, please have a look at the example in the examples directory of the //! [repository](https://github.com/najamelan/async_runtime). //! //! For the documentation, docs.rs does not make the wasm specific parts available, but their use //! is identical to the `rt` module for other targets. The only difference is that even though it's //! on a local pool (wasm does not have threads), you don't need to call run because the browser //! automatically runs the promises. This might change in the future. //! //! For running the integration tests: //! ```bash //! cargo install wasm-pack wasm-bindgen-cli //! ``` //! Now you can do either: //! ```bash //! wasm-pack test --firefox --headless //! ``` //! or: //! ```bash //! cargo test --target wasm32-unknown-unknown //! ``` //! //! ## API //! //! Api documentation can be found on [docs.rs](https://docs.rs/async_runtime). //! //! //! ## Contributing //! //! This repository accepts contributions. Ideas, questions, feature requests and bug reports can be filed through github issues. //! //! Pull Requests are welcome on github. By commiting pull requests, you accept that your code might be modified and reformatted to fit the project coding style or to improve the implementation. Please discuss what you want to see modified before filing a pull request if you don't want to be doing work that might be rejected. //! //! //! ### Code of conduct //! //! Any of the behaviors described in [point 4 "Unacceptable Behavior" of the Citizens Code of Conduct](http://citizencodeofconduct.org/#unacceptable-behavior) are not welcome here and might get you banned. If anyone including maintainers and moderators of the project fail to respect these/your limits, you are entitled to call them out. //! //! ## License //! //! [Unlicence](https://unlicense.org/) // #![ feature( async_await ) ] #![forbid( unsafe_code ) ] #![ warn ( missing_debug_implementations , missing_docs , nonstandard_style , rust_2018_idioms , )] #![allow( clippy::suspicious_else_formatting ) ] #[ cfg(not( target_arch = "wasm32" )) ] pub mod rt ; #[ cfg(not( target_arch = "wasm32" )) ] pub use { rt::exec03::* } ; #[ cfg( target_arch = "wasm32" ) ] pub mod wasm_rt ; #[ cfg( target_arch = "wasm32" ) ] pub use { wasm_rt::wasm_exec::*, wasm_rt as rt } ; mod error; mod rt_config; pub use { error :: * , rt_config :: * , }; mod import { pub use { once_cell :: { unsync::OnceCell, unsync::Lazy, unsync_lazy } , failure :: { Backtrace, Fail, Context as FailContext } , std :: { fmt, future::Future, rc::Rc, cell::RefCell, pin::Pin } , futures :: { prelude :: { Stream, Sink } , channel :: { oneshot, mpsc } , future :: { FutureExt, TryFutureExt } , task :: { Spawn, SpawnExt, LocalSpawn, LocalSpawnExt, Context as TaskContext, Poll } , stream :: { StreamExt } , sink :: { SinkExt } , executor:: { LocalPool as LocalPool03 , LocalSpawner as LocalSpawner03 , ThreadPool as ThreadPool03 , }, }, }; }