Nội dung cập nhật liên quan đến GuzzleHttp guzzlehttp/guzzle
Các cuộc gọi đồng thời/song song hiện được thực hiện thông qua một vài phương pháp khác nhau bao gồm cả Promises .. Concurrent Requests
Cách cũ để truyền mảng RequestInterfaces sẽ không hoạt động nữa.
Xem ví dụ đây
$newClient = new \GuzzleHttp\Client(['base_uri' => $base]);
foreach($documents->documents as $doc){
$params = [
'language' =>'eng',
'text' => $doc->summary,
'apikey' => $key
];
$requestArr[$doc->reference] = $newClient->getAsync('/1/api/sync/analyze/v1?' . http_build_query($params));
}
$time_start = microtime(true);
$responses = \GuzzleHttp\Promise\unwrap($requestArr); //$newClient->send($requestArr);
$time_end = microtime(true);
$this->get('logger')->error(' NewsPerf Dev: took ' . ($time_end - $time_start));
Cập nhật: Như đã đề cập trong ý kiến và đề nghị bởi @ Sankalp-tambe, bạn cũng có thể sử dụng một cách tiếp cận khác nhau để tránh điều đó một tập hợp các yêu cầu đồng thời với một thất bại sẽ không trả lại tất cả các câu trả lời.
Mặc dù các tùy chọn được đề xuất với Hồ bơi là khả thi nhưng tôi vẫn thích lời hứa.
Một ví dụ với lời hứa là sử dụng các phương thức giải quyết và chờ đợi thay vì bỏ qua.
Sự khác biệt từ ví dụ trên sẽ là
$responses = \GuzzleHttp\Promise\settle($requestArr)->wait();
Tôi đã tạo ra một ví dụ đầy đủ dưới đây để tham khảo về cách xử lý các phản ứng $ quá.
require __DIR__ . '/vendor/autoload.php';
use GuzzleHttp\Client as GuzzleClient;
use GuzzleHttp\Promise as GuzzlePromise;
$client = new GuzzleClient(['timeout' => 12.0]); // see how i set a timeout
$requestPromises = [];
$sitesArray = SiteEntity->getAll(); // returns an array with objects that contain a domain
foreach ($sitesArray as $site) {
$requestPromises[$site->getDomain()] = $client->getAsync('http://' . $site->getDomain());
}
$results = GuzzlePromise\settle($requestPromises)->wait();
foreach ($results as $domain => $result) {
$site = $sitesArray[$domain];
$this->logger->info('Crawler FetchHomePages: domain check ' . $domain);
if ($result['state'] === 'fulfilled') {
$response = $result['value'];
if ($response->getStatusCode() == 200) {
$site->setHtml($response->getBody());
} else {
$site->setHtml($response->getStatusCode());
}
} else if ($result['state'] === 'rejected') {
// notice that if call fails guzzle returns is as state rejected with a reason.
$site->setHtml('ERR: ' . $result['reason']);
} else {
$site->setHtml('ERR: unknown exception ');
$this->logger->err('Crawler FetchHomePages: unknown fetch fail domain: ' . $domain);
}
$this->entityManager->persist($site); // this is a call to Doctrines entity manager
}
Mã ví dụ này ban đầu được đăng here.
Có [bản trình diễn này] (http://guzzlephp.org/http-client/client.html#sending-requests-in-parallel) trong tài liệu. Đây vẫn là một cuộc gọi đồng bộ từ quan điểm của bạn, nhưng sẽ song song trong nội bộ - do đó tổng thời gian cho cuộc gọi sẽ chỉ là thời gian cho lần tìm kiếm dài nhất duy nhất. – halfer