Skip to content

Commit

Permalink
add example of using multi-thread tokio runtime (#294)
Browse files Browse the repository at this point in the history
* add example of using multi-thread tokio runtime

* Update multi_thread_system.rs

Co-authored-by: Rob Ede <robjtede@icloud.com>
  • Loading branch information
fakeshadow and robjtede committed Mar 24, 2021
1 parent 0c73f13 commit b7bfff2
Showing 1 changed file with 60 additions and 0 deletions.
60 changes: 60 additions & 0 deletions actix-rt/examples/multi_thread_system.rs
@@ -0,0 +1,60 @@
//! An example on how to build a multi-thread tokio runtime for Actix System.
//! Then spawn async task that can make use of work stealing of tokio runtime.

use actix_rt::System;

fn main() {
System::with_tokio_rt(|| {
// build system with a multi-thread tokio runtime.
tokio::runtime::Builder::new_multi_thread()
.worker_threads(2)
.enable_all()
.build()
.unwrap()
})
.block_on(async_main());
}

// async main function that acts like #[actix_web::main] or #[tokio::main]
async fn async_main() {
let (tx, rx) = tokio::sync::oneshot::channel();

// get a handle to system arbiter and spawn async task on it
System::current().arbiter().spawn(async {
// use tokio::spawn to get inside the context of multi thread tokio runtime
let h1 = tokio::spawn(async {
println!("thread id is {:?}", std::thread::current().id());
std::thread::sleep(std::time::Duration::from_secs(2));
});

// work stealing occurs for this task spawn
let h2 = tokio::spawn(async {
println!("thread id is {:?}", std::thread::current().id());
});

h1.await.unwrap();
h2.await.unwrap();
let _ = tx.send(());
});

rx.await.unwrap();

let (tx, rx) = tokio::sync::oneshot::channel();
let now = std::time::Instant::now();

// without additional tokio::spawn, all spawned tasks run on single thread
System::current().arbiter().spawn(async {
println!("thread id is {:?}", std::thread::current().id());
std::thread::sleep(std::time::Duration::from_secs(2));
let _ = tx.send(());
});

// previous spawn task has blocked the system arbiter thread
// so this task will wait for 2 seconds until it can be run
System::current().arbiter().spawn(async move {
println!("thread id is {:?}", std::thread::current().id());
assert!(now.elapsed() > std::time::Duration::from_secs(2));
});

rx.await.unwrap();
}

0 comments on commit b7bfff2

Please sign in to comment.