添加对 mongodb 的异步调用后,带有 mongodb 项目的 actix web 无法构建

actix web with mongodb project fails to build after an async call to mongodb is added

我正在使用 actix-web 和 mongodb 实现 REST API 作为数据后端。我正在使用来自 crates.io 和 Rust 1.46.

的官方 rust-mongodb 驱动程序版本 1.1.1

如果我添加代码来调用 mongodb 集合以获取记录,例如,即使 cargo check 没有显示任何错误或警告,cargo build 也会花费很长时间并且然后以无法编译我的项目和 (signal 9, SIGKILL: kill) 的错误终止。查找问题后,我知道这可能是 build/linking 过程中导致的内存不足错误。我正在使用 16GB RAM 的 Debian 10 机器,所以这不是很合理。

只有当我使用 asyncawait 在“处理程序”中的代码中进行调用时才会发生这种情况。

例如,如果我尝试像这样获取样本集合的名称:

pub async fn samples() -> Result<HttpResponse, Error> {
    let dbnames = get_samples().await;

    Ok(HttpResponse::Ok().json(dbnames.unwrap()))
}

async fn get_samples() -> Result<Vec<String>, ServiceError> {
    let mut dbnames: Vec<String> = Vec::new();
    let client_uri = String::from("mongodb+srv://<...MONGODB_CONNECTION_INFO...>/sample_mflix?retryWrites=true&w=majority");
    let client = mongodb::Client::with_uri_str(client_uri.as_ref()).await?;

    for name in client.list_database_names(None, None).await? {
        dbnames.push(format!("- {}", name));
    }

    Ok(dbnames)
}

cargo build 将永远不会完成并将因上述错误而停止。

为了确保,我直接在主函数 main.rs 中使用代码获取示例集合名称,它没有任何问题,编译和构建时间也很合理。

let client = mongodb::Client::with_uri_str(client_uri.as_ref()).await;
println!("Databases:");
for name in client.unwrap().list_database_names(None, None).await {
    for item in name {
        println!("- {}", item);
    }
}

即使使用 cargo build --release 来避免调试信息过多,结果也相同

只有在使用 rust-mongodb 驱动程序的异步 API 时才会发生这种情况。使用同步 API 一切都会正常构建和运行。

这可能是什么原因?

使用异步 API 升级到 1.1.1 后,我遇到了完全相同的问题。 cargo build 永远不会完成,它会消耗 100% CPU 并且会一直消耗内存直到耗尽。

发现相关问题:

两种解决方法:

  • 降级到 Rust 1.45.2
  • 切换到 async-std-runtime 以解决此问题。 mongodb = { version = "1.1.1", default-features = false, features = ["async-std-runtime"] }