При использовании AWS PHP SDK 3.x существует ли способ пакетной загрузки составных файлов в S3 параллельно с использованием массива getCommand?

Я работаю над процессом загрузки большого количества файлов на S3, а для своих небольших файлов я создаю список команд, используя getCommand для их одновременной загрузки, например:

$commands = array();
$commands[] = $s3Client->getCommand('PutObject', array(
    'Bucket' => 'mybucket',
    'Key'    => 'filename.ext',
    'Body'   => fopen('filepath', 'r'),
));
$commands[] = $s3Client->getCommand('PutObject', array(
    'Bucket' => 'mybucket',
    'Key'    => 'filename_2.ext',
    'Body'   => fopen('filepath_2', 'r'),
));
etc.

try {
    $pool = new CommandPool($s3Client, $commands, [
        'concurrency' => 5,
        'before' => function (CommandInterface $cmd, $iterKey) {
            //Do stuff before the file starts to upload
        },
        'fulfilled' => function (ResultInterface $result, $iterKey, PromiseInterface $aggregatePromise) {
            //Do stuff after the file is finished uploading
        },
        'rejected' => function (AwsException $reason, $iterKey, PromiseInterface $aggregatePromise) {
            //Do stuff if the file fails to upload
        },
    ]);

    // Initiate the pool transfers
    $promise = $pool->promise();

    // Force the pool to complete synchronously
    $promise->wait();

    $promise->then(function() { echo "All the files have finished uploading!"; });
} catch (Exception $e) {
    echo "Exception Thrown: Failed to upload: ".$e->getMessage()."<br>\n";
}

Это прекрасно работает для небольших файлов, но некоторые из моих файлов достаточно велики, и я бы хотел, чтобы они автоматически загружались в несколько частей. Итак, вместо использования getCommand('PutObject'), которое загружает файл целиком, я хотел бы использовать что-то вроде getCommand('ObjectUploader'), чтобы большие файлы можно было автоматически разбивать по мере необходимости. Однако, когда я пытаюсь использовать getCommand('ObjectUploader'), он выдает ошибку и говорит, что не знает, что с этим делать. Я предполагаю, что, возможно, команда имеет другое имя, поэтому она выдает ошибку. Но также возможно, что это невозможно сделать так.

Если вы работали над чем-то подобным в прошлом, как вы это делали? Или даже если вы не работали над этим, я открыт для любых ваших идей.

Спасибо!

Ссылки: https://docs.aws.amazon.com/sdk-for-php/v3/developer-guide/guide_commands.html#command-pool https://docs.aws.amazon.com/sdk-for-php/v3/developer-guide/s3-multipart-upload.html#object-uploader


person Adam Ellis    schedule 28.10.2020    source источник


Ответы (1)


Я решил пойти другим путем и вместо массива одновременных команд теперь использую набор одновременных промисов MultipartUploader, как показано в примере на этой странице: https://500.keboola.com/parallel-multipart-uploads-to-s3-in-php-61ff03ffc043

Вот основные сведения:

//Create an array of your file paths
$files = ['file1', 'file2', ...];

//Create an array to hold the promises
$promises = [];

//Create MultipartUploader objects, and add them to the promises array
foreach($files as $filePath) {
  $uploader = new \Aws\S3\MultipartUploader($s3Client, $filePath, $uploaderOptions);
  $promises[$filePath] = $uploader->promise();
}

//Process the promises once they are all complete
$results = \GuzzleHttp\Promise\unwrap($promises);
person Adam Ellis    schedule 28.10.2020