update example

This commit is contained in:
fakeshadow 2021-04-17 13:56:12 +08:00
parent e6944c52d1
commit 20a363c185
2 changed files with 29 additions and 44 deletions

View File

@ -17,44 +17,26 @@ fn 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 {
// use System::spawn to get inside the context of multi thread tokio runtime
let h1 = System::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 {
// work stealing occurs for this task spawn
let h2 = System::spawn(async {
println!("thread id is {:?}", std::thread::current().id());
assert!(now.elapsed() > std::time::Duration::from_secs(2));
});
rx.await.unwrap();
h1.await.unwrap();
h2.await.unwrap();
// note actix_rt can not be used in System::spawn
let res = System::spawn(async {
let _ = actix_rt::spawn(actix_rt::task::yield_now()).await;
})
.await;
// result would always be JoinError with panic message logged.
assert!(res.is_err());
}

View File

@ -148,24 +148,27 @@ impl System {
/// Send an async task to [System] and spawn running it.
/// Returned [JoinHandle](crate::task::JoinHandle) can be used to await for the task's output.
///
/// # Error
/// # Panics
/// Panics if no system is registered on the current thread.
///
/// # Errors
/// [actix_rt::spawn](crate::spawn) can not be used inside `System::spawn`.
pub fn spawn<T>(task: T) -> JoinHandle<T::Output>
where
T: Future + Send + 'static,
T::Output: Send + 'static,
{
let (tx, rx) = oneshot::channel();
CURRENT.with(|cell| match *cell.borrow() {
Some(ref sys) => sys.arbiter_handle.spawn(async {
let res = tokio::spawn(task).await;
let _ = tx.send(res);
}),
None => panic!("System is not running"),
});
tokio::spawn(async {
let (tx, rx) = oneshot::channel();
CURRENT.with(|cell| match *cell.borrow() {
Some(ref sys) => sys.arbiter_handle.spawn(async {
let res = tokio::spawn(task).await;
let _ = tx.send(res);
}),
None => panic!("System is not running"),
});
// unwrap would be caught by tokio and output as JoinError
rx.await.unwrap().unwrap()
})