Hacker News new | ask | show | jobs
by half-kh-hacker 1012 days ago
so it's clear to non-Rust devs, we do have basic primitives for "running async code from sync":

https://docs.rs/futures/latest/futures/executor/fn.block_on....

imagine you have an:

    async fn do_things() -> Something { /* ... */ }
you can:

    use futures::executor::block_on;
    fn my_normal_code() {
      let something = block_on(do_things());
    }

but this does get messy if the async code you're running isn't runtime-agnostic :(
2 comments

> You can break the chain by commanding the entire runtime to block on the completion of a future, but you probably shouldn’t do this pervasively since it isn’t composable. If a function blocks on a future, and that future calls a function that blocks on a future, congrats! The runtime panics!

article says you can panic if you use the pattern you show. specifically, if you call `my_normal_code()` from an async context.

is the author just talking about a quirk in tokio? or is this sort of wrapping intrinsically dangerous somehow?

It's not intrinsic to async functions; you can block on a future inside another future via e.g. pollster or even manual polling.
In the .Net/C# world library users just expect that the library has implemented both DoThings() and DoThingsAsync(). However that is easier said that done because many of the foundational low-level IO APIs were implemented by Microsoft that first implemented IoMethod() and then implemented IoMethodAsync() when async/await became a thing in C#.