我如何断定Rust期货预览期货尚未解决

时间:2019-10-10 13:05:16

标签: rust

我正在尝试使依赖关系保持最新。我有一些使用Futures-Preview和Futures-Timer的代码。较早版本的Futures-Timer包含了对未来进行超时的功能,我已经进行了使用此功能的测试,但这是最新版本中的removed

有没有一种简单的方法可以检查未来是否已经解决,然后再通过测试呢? (而且,“已解决”的单词正确吗?)

我尝试使用f1.poll(),但无法完全弄清楚返回类型以及如何使用它。

我也尝试使用timeout from async_std,但在这些方面出现了很多错误:

error[E0008]: cannot bind by-move into a pattern guard
   --> /Users/nathan/.cargo/registry/src/github.com-1ecc6299db9ec823/async-std-0.99.9/src/net/driver/mod.rs:207:17
    |
207 |             Err(err) if err.kind() == io::ErrorKind::WouldBlock => {}
    |                 ^^^ moves value into pattern guard
    |
    = help: add `#![feature(bind_by_move_pattern_guards)]` to the crate attributes to enable

除非我弄错了,那是要我修改async-std,对吗?有办法解决吗?

这是我的考试:

#[cfg(test)]
mod tests {
    use super::*;
    use crate::threadpool::ThreadPool;
    use futures_timer::TryFutureExt;

    // ....

    #[test]
    fn test_trigger_future_untriggered() {
        let tf = TriggerFuture::default();
        let f1 = tf.future();

        ThreadPool::default()
            .spawn_wait::<_, _, ()>(async {
                f1.map(|_| Result::<(), std::io::Error>::Ok(()))
                    .timeout(std::time::Duration::from_millis(50))
                    .await
                    .expect_err("expected timeout");
                Ok(())
            })
            .expect("expected!");
    }
}

更新:这是我尝试的另一件事。对于Futures-Timer v1.0.1,如果我取消对tf.trigger()的注释,它会按预期失败,但是如果我不这样做,它将永远运行。怎么了?

    #[test]
    fn test_trigger_future_untriggered() {
        let tf = TriggerFuture::default();
        let f1 = tf.future();

        // tf.trigger();

        ThreadPool::default()
            .spawn_wait::<_, _, _>(async {
                use futures_timer::Delay;
                let delay = Delay::new(std::time::Duration::from_millis(50));
                future::select(f1, delay).then(|either| {
                    match either {
                        Either::Left((_, b)) => b.map(move |y| (Err("this future shoudn't resolve"), y)).left_future(),
                        Either::Right((_, a)) => a.map(move |x| (Ok("expected timeout"), x)).right_future(),
                    }
                }).await.0
            })
            .expect("expected!");
    }

这是我要求的Cargo.toml:

[package]
name = "shared_futures"
version = "0.1.0"
publish = false
edition = "2018"

[dependencies]
futures-preview = { version = "0.3.0-alpha.19", features = [ "async-await", "compat" ] }
crossbeam-channel = "0.3.9"
num_cpus = "1.10.1"
# Note: the timeout feature was removed in futures-timer v0.6
futures-timer = "1.0.1"

[features]
sanitizer_safe = []

[lib]
name = "shared_futures"
crate-type = ["rlib"]

2 个答案:

答案 0 :(得分:1)

能否请您张贴Cargo.toml以及属于示例代码的任何use语句?我无法运行您的代码,但是在查看了您的测试示例和错误消息后,我相信有些related questions(和此处)可能会对您有所帮助。

您可以尝试更新到每晚的最新版本,看看是否可以解决该问题?该功能似乎是recently stabilized

rustup update nightly

这是假设您正在使用rust编译器的夜间版本。

好运。

答案 1 :(得分:0)

(在一些帮助下)找到了答案。我最后的尝试是接近,但做得太多。这是一个实际可行的简化版本:

    #[test]
    fn test_trigger_future_untriggered() {
        let tf = TriggerFuture::default();
        let f1 = tf.future();

        tf.trigger();

        ThreadPool::default()
            .spawn_wait::<_, _, &str>(async {
                use futures_timer::Delay;
                let delay = Delay::new(std::time::Duration::from_millis(50));
                let res = future::select(f1, delay).await;
                match res {
                    Either::Left(..) => Err("The TriggerFuture resolved first"),
                    Either::Right(..) => Ok(()),
                }
            })
            .expect("The Delay should have resolved first");
    }