Почему загрузка файла с S3 с помощью Rusoto иногда возвращает пустую строку?

Пытаюсь получить тело из существующего файла в ведре S3 с помощью русото. Мой body.unwrapвозвращает пустую строку, и я не понимаю почему. У меня нет проблем или ошибок, и мой файл в порядке.

Похоже, я иногда получаю пустой контент от S3. Это быстрый и грязный патч, есть ли другой способ лучше? Нравится использовать хеш S3?

pub fn get_object(
    access_key_id: &str,
    secret_access_key: &str,
    region: &Region,
    bucket_name: &str,
    object_key: &str,
) -> Result<FileContent, Error> {
    let credentials = StaticProvider::new(
        access_key_id.to_string(),
        secret_access_key.to_string(),
        None,
        None,
    );

    let client = Client::new_with(credentials, HttpClient::new().unwrap());
    let s3_client = S3Client::new_with_client(client, region.clone());

    let mut or = GetObjectRequest::default();
    or.bucket = bucket_name.to_string();
    or.key = object_key.to_string();
    let _ = env_logger::try_init();
    let get_object_output = s3_client.get_object(or);
    let r = async_run(get_object_output);

    let _err = Error::new(
        ErrorKind::Other,
        format!(
            "something goes wrong while getting object {} in the S3 bucket {}",
            object_key, bucket_name
        ),
    );

    match r {
        Err(err) => {
            warn!("{}", err);
            Err(_err)
        }

        Ok(x) => {
            let mut s = String::new();
            x.body.unwrap().into_blocking_read().read_to_string(&mut s);

            if s.is_empty() {
                // It looks like we receive sometimes empty content from s3. This is a quick and dirty patch, is there another better way ? Like using s3 Hash ?
                return Err(Error::new(
                    ErrorKind::InvalidData,
                    "file content is empty - which is not the expected content - what's wrong?",
                ));
            }

            Ok(s)
        }
    }
}

Это моя интеграция с Tokio:

use std::future::Future;
use tokio::runtime::Runtime;

pub fn async_run<F: Future>(future: F) -> F::Output {
    // TODO improve - is it efficient to create a Runtime at each exec?
    let mut runtime = Runtime::new().expect("unable to create a tokio runtime");
    runtime.block_on(future)
}

Похоже, Tokio не работает должным образом.

Решаю свои проблемы: у меня очень низкая скорость интернета, я использую AWS CLI в случае нескольких сбоев из rusoto.

0 ответов

Другие вопросы по тегам