Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FutureExt::now_or_never always returning None when using futures_timer::Delay #2745

Open
foohyfooh opened this issue May 19, 2023 · 2 comments

Comments

@foohyfooh
Copy link

I am trying to write something to wait some time and check the async function is finished so I was using FutureExt::now_or_never but it is giving me unexpected output. The following is the example program I was using to test.

Cargo.toml

[package]
name = "futures-test"
version = "0.1.0"
edition = "2021"

[dependencies]
futures = "0.3.28"
futures-timer = "3.0.2"

main.rs

use std::time::Duration;
use futures::{FutureExt, executor};
use futures_timer::Delay;

async fn wait_for_signal() -> i32 {
    Delay::new(Duration::from_millis(5)).await;
    return 42
}

fn main() {
    let timeout = Duration::from_secs(5);
    let signal_future = wait_for_signal();
    executor::block_on(Delay::new(timeout));
    let signal = signal_future.now_or_never();
    println!("Signal: {:?}", signal);
    // if signal.is_none() {
    //     println!("Timed out");
    // } else {
    //     println!("Got data");
    // }
}

The output I am getting is None even though the delay in wait_for_signal should have already been done.

   Compiling futures-test v0.1.0 (/root/futures-test)
    Finished dev [unoptimized + debuginfo] target(s) in 0.20s
     Running `target/debug/futures-test`
Signal: None

But if I comment out Delay::new(Duration::from_millis(5)).await; in wait_for_signal, it is giving me what I expect.

   Compiling futures-test v0.1.0 (/root/futures-test)
    Finished dev [unoptimized + debuginfo] target(s) in 0.21s
     Running `target/debug/futures-test`
Signal: Some(42)
@foohyfooh foohyfooh changed the title FutureExt::now_or_never always returning None when using future_timer::Delay FutureExt::now_or_never always returning None when using futures_timer::Delay May 19, 2023
@wishawa
Copy link

wishawa commented May 22, 2023

See this playground.
You might think that the 5 seconds wait started when signal_future was created - in the line

let signal_future = wait_for_signal();

But async code are lazy and do nothing unless polled. The body of wait_for_signal wasn't executed until when the signal_future was polled in the line

let signal = signal_future.now_or_never();

@foohyfooh
Copy link
Author

Playground Code
Thanks to your playground I noticed something interesting between the handling of sleep vs Delay. now_or_never waits for the future when using sleep for the additional time and returns the value; but doesn't do that with Delay and returns the None.
Since playground only gives the output after the whole program is run or halted, you may be required to run the playground code locally to properly see the difference.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants