无法使异步关闭与Warp :: Filter一起使用

时间:2020-10-01 00:19:03

标签: rust closures rust-warp

我正在尝试使Error in tempfile(pattern = "_rs_rdf_", tmpdir = outputFolder, fileext = ".rdf") : temporary name too long 的{​​{1}}过滤器中的异步关闭起作用。

这是我能想到的最小的例子,我有理由确定我没有遗漏任何重要的细节:

and_then

我正在使用:

Warp

错误是:

use std::{convert::Infallible, sync::Arc, thread, time};
use tokio::sync::RwLock;
use warp::Filter;

fn main() {
    let man = Manifest::new();

    let check = warp::path("updates").and_then(|| async move { GetAvailableBinaries(&man).await });
}

async fn GetAvailableBinaries(man: &Manifest) -> Result<impl warp::Reply, Infallible> {
    Ok(warp::reply::json(&man.GetAvailableBinaries().await))
}

pub struct Manifest {
    binaries: Arc<RwLock<Vec<i32>>>,
}

impl Manifest {
    pub fn new() -> Manifest {
        let bins = Arc::new(RwLock::new(Vec::new()));

        thread::spawn(move || async move {
            loop {
                thread::sleep(time::Duration::from_millis(10000));
            }
        });

        Manifest { binaries: bins }
    }

    pub async fn GetAvailableBinaries(&self) -> Vec<i32> {
        self.binaries.read().await.to_vec()
    }
}

2 个答案:

答案 0 :(得分:0)

我不确定这是您要做什么,但是此解决方案为我构建:

pointer-events:none;

use std::{convert::Infallible, sync::Arc, thread, time}; use tokio::sync::RwLock; use warp::Filter; fn main() { let man = Manifest::new(); let check = warp::path("updates").and_then(|| async { GetAvailableBinaries(&man).await }); } async fn GetAvailableBinaries(man: &Manifest) -> Result<impl warp::Reply, Infallible> { Ok(warp::reply::json(&man.GetAvailableBinaries().await)) } #[derive(Clone)] pub struct Manifest { binaries: Arc<RwLock<Vec<i32>>>, } impl Manifest { pub fn new() -> Manifest { let bins = Arc::new(RwLock::new(Vec::new())); thread::spawn(move || async { loop { thread::sleep(time::Duration::from_millis(10000)); //mutate bins here } }); Manifest { binaries: bins } } pub async fn GetAvailableBinaries(&self) -> Vec<i32> { self.binaries.read().await.to_vec() } } 是编译器发出有关签名警告的原因:move。这意味着该闭包中引用的所有内容都将移入该闭包的上下文中。在这种情况下,编译器不能保证闭包为let check = warp::path("updates").and_then(|| async move { GetAvailableBinaries(&man).await });,而只能保证Fn意味着闭包只能保证执行一次。

答案 1 :(得分:-1)

在使Manifest实现Clone之后,您可以通过平衡清单对象时的平衡来纠正错误:

fn main() {
    let man = Manifest::new();

    let check = warp::path("updates").and_then(move || {
        let man = man.clone();
        async move { get_available_binaries(&man).await }
    });

    warp::serve(check);
}

这会将man移到传递给and_then的闭包中,然后在每次执行闭包时向异步块提供man的副本。然后,异步块将拥有该数据,并可以对其进行引用,而不必担心在数据被释放之后执行将来的事情。