AWS SDK for PHPでasyncを使ってみる
jQueryのDeferredのように使えそうな感じ。
S3ClientのPutObjectメソッドを使って動作を確認してみます。
まずは同期実行のパターン。
<?php
require 'vendor/autoload.php';
date_default_timezone_set('Asia/Tokyo');
use Aws\S3\S3Client;
// 設定値
$credentials = [
'key' => '*****************',
'secret' => '**************************************',
];
$bucketName = 'my-bucket';
// 100MBのダミーファイルを作成
$filesize = 104857600;
$dummyFile = 'dummy.dat';
$fp = fopen($dummyFile, 'wb');
ftruncate($fp, $filesize);
fclose($fp);
// --- S3にファイルアップロード(同期)---
$s3client = S3Client::factory([
'credentials' => $credentials,
'region' => 'ap-northeast-1',
'version' => 'latest',
]);
// タイマーセット
$timer = microtime(true);
echo 'アップロード開始:' . date('Y/m/d H:i:s') . PHP_EOL;
for($i = 0; $i < 10; $i++){
$fileName = uniqid() . '.dat';
$result = $s3client->putObject([
'Bucket' => $bucketName,
'Key' => 'dummy/' . $fileName,
'SourceFile' => $dummyFile,
]);
}
echo 'アップロード終了:' . (microtime(true) - $timer) . '秒' . PHP_EOL;
>php sync.php
アップロード開始:2020/05/02 16:13:22
アップロード終了:85.937815189362秒
>aws s3 ls s3://my-bucket/dummy/
2020-05-02 16:13:24 104857600 5ead1d920e20d.dat
2020-05-02 16:13:31 104857600 5ead1d98daad5.dat
2020-05-02 16:13:40 104857600 5ead1da2be3cc.dat
2020-05-02 16:13:53 104857600 5ead1daf57494.dat
2020-05-02 16:14:03 104857600 5ead1db8ce204.dat
2020-05-02 16:14:10 104857600 5ead1dc092234.dat
2020-05-02 16:14:22 104857600 5ead1dcc32340.dat
2020-05-02 16:14:30 104857600 5ead1dd3ee445.dat
2020-05-02 16:14:37 104857600 5ead1ddb0cc76.dat
2020-05-02 16:14:43 104857600 5ead1de166785.dat
次は非同期実行のパターン。
<?php
require 'vendor/autoload.php';
date_default_timezone_set('Asia/Tokyo');
use Aws\S3\S3Client;
use Guzzlehttps\Promise;
// 設定値
$credentials = [
'key' => '*****************',
'secret' => '**************************************',
];
$bucketName = 'my-bucket';
// 100MBのダミーファイルを作成
$filesize = 104857600;
$dummyFile = 'dummy.dat';
$fp = fopen($dummyFile, 'wb');
ftruncate($fp, $filesize);
fclose($fp);
// --- S3にファイルアップロード(非同期)---
$s3client = S3Client::factory([
'credentials' => $credentials,
'region' => 'ap-northeast-1',
'version' => 'latest',
]);
// タイマーセット
$timer = microtime(true);
echo 'アップロード開始:' . date('Y/m/d H:i:s') . PHP_EOL;
for($i = 0; $i < 10; $i++){
$fileName = uniqid() . '.dat';
$promise = $s3client->putObjectAsync([
'Bucket' => $bucketName,
'Key' => 'dummy/' . $fileName,
'SourceFile' => $dummyFile,
]);
$promises[] = $promise;
}
$aggregate = Promise\all($promises);
$aggregate->wait(); // ここでS3へのリクエストが実行される
echo 'アップロード終了:' . (microtime(true) - $timer) . '秒' . PHP_EOL;
>php async.php
アップロード開始:2020/05/02 16:17:06
アップロード終了:42.00698018074秒
>aws s3 ls s3://my-bucket/dummy/
2020-05-02 16:17:15 104857600 5ead1e729d531.dat
2020-05-02 16:17:15 104857600 5ead1e72a2b36.dat
2020-05-02 16:17:15 104857600 5ead1e72a3657.dat
2020-05-02 16:17:15 104857600 5ead1e72a3ced.dat
2020-05-02 16:17:15 104857600 5ead1e72a4316.dat
2020-05-02 16:17:15 104857600 5ead1e72a4938.dat
2020-05-02 16:17:15 104857600 5ead1e72a4f69.dat
2020-05-02 16:17:15 104857600 5ead1e72a58dd.dat
2020-05-02 16:17:15 104857600 5ead1e72a60d1.dat
2020-05-02 16:17:15 104857600 5ead1e72a6733.dat
同時にアップロード処理がコミットされたのか、S3側のタイムスタンプが全く同じ時刻になっています。
なるほど、うまく使えばSDKを使ったコードの実行速度を向上させられそうですが、非同期処理はエラートラップや実行順序の制御が難しくなるので注意が必要ですね。
ディスカッション
コメント一覧
まだ、コメントがありません