添加对 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 机器,所以这不是很合理。
只有当我使用 async
和 await
在“处理程序”中的代码中进行调用时才会发生这种情况。
例如,如果我尝试像这样获取样本集合的名称:
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 并且会一直消耗内存直到耗尽。
发现相关问题:
- https://jira.mongodb.org/browse/RUST-558
- https://github.com/actix/actix-web/issues/1688
- https://github.com/rust-lang/rust/issues/75992
两种解决方法:
- 降级到 Rust 1.45.2
- 切换到 async-std-runtime 以解决此问题。
mongodb = { version = "1.1.1", default-features = false, features = ["async-std-runtime"] }
我正在使用 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 机器,所以这不是很合理。
只有当我使用 async
和 await
在“处理程序”中的代码中进行调用时才会发生这种情况。
例如,如果我尝试像这样获取样本集合的名称:
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 并且会一直消耗内存直到耗尽。
发现相关问题:
- https://jira.mongodb.org/browse/RUST-558
- https://github.com/actix/actix-web/issues/1688
- https://github.com/rust-lang/rust/issues/75992
两种解决方法:
- 降级到 Rust 1.45.2
- 切换到 async-std-runtime 以解决此问题。
mongodb = { version = "1.1.1", default-features = false, features = ["async-std-runtime"] }