rmanoka / async-scoped

A scope for async_std and tokio to spawn non-static futures
117 stars 14 forks source link

panic when calling scope_and_block #2

Closed orbli closed 3 years ago

orbli commented 4 years ago

Glad to be the first issue here. I happened to have a need of scoped task and come across your repo.

When i run scope_and_block() within async-std runtime it returns

thread 'async-std/runtime' panicked at 'cannot call `Executor::enter()` if already inside an `Executor`', /rustc/5c1f21c3b82297671ad3ae1e8c942d2ca92e84f2/src/libstd/macros.rs:13:23

Would like to see if you have any clue to remove the prompt.

rmanoka commented 4 years ago

@orbli Can you provide a minimal example to reproduce the error?

orbli commented 4 years ago
use std::time::Duration;
use async_std::task;
use async_scoped::scope_and_block;

async fn some_task() {
    println!("some task");
}

async fn spawned_task() {
    scope_and_block(|s| {
        s.spawn(some_task());
    });
}

async fn async_main() {
    task::spawn(spawned_task());
    task::sleep(Duration::from_secs(1)).await;
}

fn main() {
    task::block_on(async_main());
}
rmanoka commented 4 years ago

It seems to be an issue in async-std not allowing block_on inside a spawn. The following example also causes the same error (tested with async-std release 1.6.3).

#[test]
fn test_recursive_block() {
    task::block_on(async {
        task::spawn(async {
            task::block_on(async {
                eprintln!("Hello block!");
            })
        });
    })
}
orbli commented 4 years ago

i agree your answer, sorry 😂😂😂 let's raise this to async std and see if they offer any help

rmanoka commented 4 years ago

@orbli This behaviour of async-std may be necessary to prevent deadlocks, as I believe they internally use a fixed number of worker threads to process the futures. See for instance this issue.

Unfortunately, the only safe way provided in this crate currently uses a block_on construct. I have not been actively following the async rust developments recently, so I am not sure if there is an alternative. Let us see if async-std authors offer some interesting ideas around this issue.

rmanoka commented 3 years ago

@orbli It seems the panic only happens in recent releases of async-std. If it suffices for your use-case, you can consider fixing the version of async-std in your project to 1.4.x (using something like async-std = "~1.4.0") in Cargo.toml.

Also, replacing the task::block_on with either smol::block_on or futures_lite::block_on seems to work. I should look into using one of these internally, but I am not a 100% sure how these crates plan to progress in the future. Will try to dig into code, and issues on this.

rmanoka commented 3 years ago

v0.5.0 and above do not have the panic