複数の同一サーバーに保存されている大量の大きなファイルをダウンロードする必要があります。サーバー 3 に保存されている「5.doc」などのファイルは、サーバー 55 にも保存されます。
これを高速化するために、1 つのサーバーだけを使用してすべてのファイルを 1 つずつダウンロードするのではなく、すべてのサーバーを同時に使用しています。問題は、サーバーの 1 つが他のサーバーよりもはるかに遅いか、ダウンしている可能性があることです。Guzzle を使用してファイルをバッチ ダウンロードする場合、別のバッチを開始する前に、そのバッチ内のすべてのファイルをダウンロードする必要があります。
すべてのサーバーが常にファイルをダウンロードするように、他のファイルと一緒に別のファイルのダウンロードをすぐに開始する方法はありますか?
サーバーがダウンしている場合、タイムアウトを 300 秒に設定しました。これに達すると、Guzzle は ConnectionException をキャッチします。
どの約束 (ダウンロード) が失敗したかを特定してキャンセルできるようにするにはどうすればよいですか? どのファイル/サーバーが失敗したかについての情報を取得できますか?
以下は、ポイントを説明するために使用しているコードの簡単な例です。助けてくれてありがとう!
$filesToDownload = [['5.doc', '8.doc', '10.doc'], ['1.doc', '9.doc']]; //The file names that we need to download
$availableServers = [3, 55, 88]; //Server id's that are available
foreach ($filesToDownload as $index => $fileBatchToDownload) {
$promises = [];
foreach ($availableServers as $key => $availableServer) {
array_push(
$promises, $client->requestAsync('GET', 'http://domain.com/' . $fileBatchToDownload[$index][$key], [
'timeout' => 300,
'sink' => '/assets/' . $fileBatchToDownload[$index][$key]
])
);
$database->updateRecord($fileBatchToDownload[$index][$key], ['is_cached' => 1]);
}
try {
$results = Promise\unwrap($promises);
$results = Promise\settle($promises)->wait();
} catch (\GuzzleHttp\Exception\ConnectException $e) {
//When can't connect to the server or didn't download within timeout
foreach ($e->failed() as $failedPromise) {
//Re-set record in database to is_cached = 0
//Delete file from server
//Remove this server from the $availableServers list as it may be down or too slow
//Re-add this file to the next batch to download $filesToDownload
}
}
}