Add example of blocking environment (#1036)

This commit is contained in:
Lev Eniseev 2019-04-09 22:10:15 +03:00 committed by Carl Lerche
parent 4f819b7cd1
commit 2c4549a18a
2 changed files with 89 additions and 0 deletions

View File

@ -55,6 +55,8 @@ A high level description of each example is:
* [`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!

View File

@ -0,0 +1,87 @@
//! 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.
extern crate tokio;
extern crate tokio_threadpool;
use std::thread;
use std::time::Duration;
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 Item = ();
type Error = ();
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
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_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 Item = ();
type Error = ();
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
println!("Non-blocking done: {}!", self.value);
Ok(Async::Ready(()))
}
}
/// This future spawns child futures.
struct SpawningFuture;
impl Future for SpawningFuture {
type Item = ();
type Error = ();
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
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);
}
Ok(Async::Ready(()))
}
}
fn main() {
let spawning_future = SpawningFuture;
let runtime = Builder::new().core_threads(4).build().unwrap();
runtime.block_on_all(spawning_future).unwrap();
}