Skip to content

Instantly share code, notes, and snippets.

@burningsky250
Last active August 9, 2024 02:17
Show Gist options
  • Select an option

  • Save burningsky250/f2fd1570825a72c65eb6cd58cf64d740 to your computer and use it in GitHub Desktop.

Select an option

Save burningsky250/f2fd1570825a72c65eb6cd58cf64d740 to your computer and use it in GitHub Desktop.
use std::thread::{self, sleep};
use std::time::Duration;
#[tokio::test]
async fn test_async_call_sync() {
fn sync_dummy_func() -> i32 {
sleep(Duration::from_secs(1));
1
}
let result = tokio::task::spawn_blocking(sync_dummy_func).await.unwrap();
println!("{result}");
}
#[test]
fn test_sync_call_async() {
async fn async_dummy_func() -> i32 {
tokio::time::sleep(Duration::from_secs(1)).await;
1
}
let runtime = tokio::runtime::Builder::new_multi_thread()
.enable_all()
.build()
.unwrap();
let result = runtime.block_on(async_dummy_func());
println!("{result}");
}
#[tokio::test(flavor = "multi_thread")]
async fn test_async_sync_async() {
async fn async_dummy_func() -> i32 {
tokio::time::sleep(Duration::from_secs(1)).await;
1
}
fn sync_dummy_func() -> i32 {
// wait for async function result in sync context
// attempt 1(failed): directly calling runtime::Handle::block_on. oooops! it will panic in runtime due to:
// 'Cannot start a runtime from within a runtime. This happens because a function (like `block_on`) attempted to block the current thread while the thread is being used to drive asynchronous tasks.'
//
// tokio::runtime::Handle::current().block_on(async_dummy_func())
// attempt 2(failed): spawn a new thread and block on waiting future
// fail reason: 'there is no reactor running, must be called from the context of a Tokio 1.x runtime'
// thread::scope(|s| {
// s.spawn(|| tokio::runtime::Handle::current().block_on(async_dummy_func()))
// .join()
// .unwrap()
// })
// attempt 3(ok): spawn a new thread and create new runtime to block on waiting future
thread::scope(|s| {
s.spawn(|| {
tokio::runtime::Runtime::new()
.unwrap()
.block_on(async_dummy_func())
})
.join()
.unwrap()
})
}
// call sync function
let result = sync_dummy_func();
println!("{result}");
}
#[test]
fn sync_async_sync() {
fn sync_dummy_func() -> i32 {
sleep(Duration::from_secs(1));
1
}
async fn async_dummy_func() -> i32 {
// async future block on sync function
tokio::task::spawn_blocking(sync_dummy_func).await.unwrap()
}
// sync function block on async future
tokio::runtime::Runtime::new()
.unwrap()
.block_on(async_dummy_func());
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment