actix web с проектом mongodb не создается после добавления асинхронного вызова mongodb

Я реализую REST API, используя actix-web и mongodb для серверной части данных. Я использую версию 1.1.1 официального драйвера rust-mongodb от crates.io и Rust 1.46.

Если я добавлю код для вызова коллекции mongodb, например, для получения записей, даже если cargo check не показывает ошибок или предупреждений, cargo build занимает много времени, а затем завершается с ошибкой, что не удалось скомпилировать мой проект и (signal 9, SIGKILL: kill). После поиска проблемы я понял, что это, вероятно, ошибка нехватки памяти, вызванная во время процесса сборки / связывания. Я работаю на машине Debian 10 с 16 ГБ ОЗУ, так что это не очень разумно.

Это происходит только тогда, когда я вызываю код внутри обработчика с использованием 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, чтобы не было слишком много отладочной информации

Это происходит только при использовании асинхронного API драйвера rust-mongodb. С помощью API синхронизации все строится и работает правильно.

Что могло быть причиной этого?


person Nikos Steiakakis    schedule 28.09.2020    source источник


Ответы (1)


У меня возникла точно такая же проблема после обновления до 1.1.1 с помощью async API. Сборка Cargo никогда не будет завершена, она будет потреблять 100% ЦП и будет использовать память до тех пор, пока не будет исчерпана.

Найдены похожие проблемы:

Два способа обхода проблемы:

  • Переход на ржавчину 1.45.2
  • Переключитесь на async-std-runtime, чтобы обойти эту проблему. mongodb = { version = "1.1.1", default-features = false, features = ["async-std-runtime"] }
person gembin    schedule 10.10.2020
comment
Попробовав его со стабильной версией 1.47 и async-std-runtime, все заработало. Скомпилировано и построено менее чем за минуту. Затем я снова попытался использовать функции по умолчанию для mongodb 1.1.1, чтобы проверить, изменилось ли обновление до 1.47 и имело ли такое же поведение, как и с rust 1.46, очень долгое время сборки, пока оно не завершилось с ошибкой. Итак, очевидно, что использование async-std-runtime помогло. - person Nikos Steiakakis; 12.10.2020
comment
Да, если использовать функции по умолчанию, необходимо понизить версию Rust 1.45.2. И async-std-runtime работает с 1.47 - person gembin; 27.10.2020