/** * Sends multiple commands concurrently and returns a hash map of commands * mapped to their corresponding result or exception. * * Note: This method keeps every command and command and result in memory, * and as such is NOT recommended when sending a large number or an * indeterminable number of commands concurrently. Instead, you should use * executeAll() and utilize the event system to work with results. * * @param ServiceClientInterface $client * @param array|\Iterator $commands Commands to send. * @param array $options Passes through the options available * in {@see ServiceClientInterface::createPool()} * * @return BatchResults * @throws \InvalidArgumentException if the event format is incorrect. */ public static function batch(ServiceClientInterface $client, $commands, array $options = []) { $hash = new \SplObjectStorage(); foreach ($commands as $command) { $hash->attach($command); } $client->executeAll($commands, RequestEvents::convertEventArray($options, ['process'], ['priority' => RequestEvents::LATE, 'fn' => function (ProcessEvent $e) use($hash) { if ($e->getException()) { $hash[$e->getCommand()] = $e->getException(); } else { $hash[$e->getCommand()] = $e->getResult(); } }])); return new BatchResults($hash); }
/** * Sends multiple requests in parallel and returns an array of responses * and exceptions that uses the same ordering as the provided requests. * * IMPORTANT: This method keeps every request and response in memory, and * as such, is NOT recommended when sending a large number or an * indeterminate number of requests concurrently. * * @param ClientInterface $client Client used to send the requests * @param array|\Iterator $requests Requests to send in parallel * @param array $options Passes through the options available in * {@see GuzzleHttp\Pool::__construct} * * @return BatchResults Returns a container for the results. * @throws \InvalidArgumentException if the event format is incorrect. */ public static function batch(ClientInterface $client, $requests, array $options = []) { $hash = new \SplObjectStorage(); foreach ($requests as $request) { $hash->attach($request); } // In addition to the normally run events when requests complete, add // and event to continuously track the results of transfers in the hash. (new self($client, $requests, RequestEvents::convertEventArray($options, ['end'], ['priority' => RequestEvents::LATE, 'fn' => function (EndEvent $e) use($hash) { $hash[$e->getRequest()] = $e->getException() ? $e->getException() : $e->getResponse(); }])))->wait(); return new BatchResults($hash); }
/** * Convenience method for sending multiple requests in parallel and * retrieving a hash map of requests to response objects or * RequestException objects. * * Note: This method keeps every request and response in memory, and as * such is NOT recommended when sending a large number or an indeterminable * number of requests in parallel. * * @param ClientInterface $client Client used to send the requests * @param array|\Iterator $requests Requests to send in parallel * @param array $options Passes through the options available in * {@see GuzzleHttp\ClientInterface::sendAll()} * * @return \SplObjectStorage Requests are the key and each value is a * {@see GuzzleHttp\Message\ResponseInterface} if the request succeeded * or a {@see GuzzleHttp\Exception\RequestException} if it failed. * @throws \InvalidArgumentException if the event format is incorrect. */ function batch(ClientInterface $client, $requests, array $options = array()) { $hash = new \SplObjectStorage(); foreach ($requests as $request) { $hash->attach($request); } // Merge the necessary complete and error events to the event listeners // so that as each request succeeds or fails, it is added to the result // hash. $options = RequestEvents::convertEventArray($options, array('complete', 'error'), array('priority' => RequestEvents::EARLY, 'once' => true, 'fn' => function ($e) use($hash) { /** @noinspection PhpUndefinedMethodInspection */ $hash[$e->getRequest()] = $e; })); // Send the requests in parallel and aggregate the results. $client->sendAll($requests, $options); // Update the received value for any of the intercepted requests. foreach ($hash as $request) { /** @var \GuzzleHttp\Event\ErrorEvent[] $hash */ if ($hash[$request] instanceof CompleteEvent) { $hash[$request] = $hash[$request]->getResponse(); } elseif ($hash[$request] instanceof ErrorEvent) { $hash[$request] = $hash[$request]->getException(); } } return $hash; }
private function preventCommandExceptions(array $options) { // Prevent CommandExceptions from being thrown return RequestEvents::convertEventArray($options, array('error'), array('priority' => RequestEvents::LATE, 'fn' => function (CommandErrorEvent $e) { $e->stopPropagation(); })); }
/** * @dataProvider prepareEventProvider */ public function testConvertsEventArrays(array $in, array $events, $add, array $out) { $result = RequestEvents::convertEventArray($in, $events, $add); $this->assertEquals($out, $result); }
/** * @expectedException \InvalidArgumentException */ public function testValidatesEventFormat() { RequestEvents::convertEventArray(['foo' => false], ['foo'], []); }