Async-std: async_std::task::sleep doesn't work with futures:executor::block_on

Created on 7 Jun 2020  路  9Comments  路  Source: async-rs/async-std

A function using async_std::task::sleep doesn't work when it's executed by futures:executor::block_on.

Versions:

  • futures: 0.3.5
  • async-std: 1.6.0
  • rustc: 1.44.0 (49cae5576 2020-06-01)

The following code will work as expected:

async fn sleep() {
    println!("Sleep!");
    async_std::task::sleep(std::time::Duration::from_secs(1)).await;
    println!("Done!");
}

#[async_std::main]
async fn main() {
    sleep().await;
}

But in the next one, async_std::task::sleep will never end:

async fn sleep() {
    println!("Sleep!");
    async_std::task::sleep(std::time::Duration::from_secs(1)).await;
    println!("Done!");
}

fn main() {
    futures::executor::block_on(sleep());
}

Does anyone have any idea on this?

Most helpful comment

I can confirm both code blocks in the first post now correctly have the same behavior with v1.6.2.

All 9 comments

Version 1.6.0 of async-std switched to using the smol runtime. Now, async_std::task::sleep() uses smol::Timer internally. smol provides the smol::run() function, whose docs state: "at least one thread has to be calling run() in order for futures waiting on I/O and timers to get notified." So the reason the second code block doesn't work is that there's no thread calling smol::run(), in contrast to the first code block where async-std calls smol::run() behind the scenes.

I see. Thank you for your explanation!

Hey, thanks for your work on async-std.

I think that this breaking change is very surprising. I just upgraded from version 1.5.0 of async-std to version 1.6.1. This change broke all of my code and tests. I wasn't expecting such breakage from a minor version bump.

Originally I chose to use async-std because it blended well enough with the rest of the code in my project, without asking for any special treatment. Now to make timer related code work I have to pollute every test function and binary entry point with the async-std decorator.

Sorry for the tough words. I know it takes much effort to develop this library. I wish I could come up with a better design, making the library's runtime less intrusive, but I also don't have an answer at this point.

@realcr not sure if you were responding to me, but I'm not an async-std author.

I should have added some context above; I too ran into this issue in my project when upgrading from 1.5.0. My code just hanged, and through some debugging I narrowed down the problem to a timer call that never returned. I then looked at the async-std source to learn what I posted above.

I definitely consider this behavior a bug, as it has broken multiple users' code, and as @realcr said, it's a breaking change in a minor version bump. Additionally, this new behavior is not documented in the release notes or crate docs.

@kenkoooo could you reopen this issue?

@Seeker14491 : Thanks, I sent this message the hope one of the maintainers sees it.
You were the one providing the solution, no complaints to you (:

@dignifiedquire This is the same issue we were looking at today. Should be fixable with another Lazy::force() :)

This should be fixed in 1.6.2, could you please retest?

@realcr this was not a breaking change, it was simply a bug

I can confirm both code blocks in the first post now correctly have the same behavior with v1.6.2.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

ghost picture ghost  路  4Comments

yoshuawuyts picture yoshuawuyts  路  3Comments

yoshuawuyts picture yoshuawuyts  路  5Comments

Lonami picture Lonami  路  5Comments

Nokel81 picture Nokel81  路  3Comments