BatchCommandTransfer.php 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. <?php
  2. namespace Guzzle\Batch;
  3. use Guzzle\Batch\BatchTransferInterface;
  4. use Guzzle\Batch\BatchDivisorInterface;
  5. use Guzzle\Common\Exception\InvalidArgumentException;
  6. use Guzzle\Service\Command\CommandInterface;
  7. use Guzzle\Service\Exception\InconsistentClientTransferException;
  8. /**
  9. * Efficiently transfers multiple commands in parallel per client
  10. * This class is to be used with {@see Guzzle\Batch\BatchInterface}
  11. */
  12. class BatchCommandTransfer implements BatchTransferInterface, BatchDivisorInterface
  13. {
  14. /** @var int Size of each command batch */
  15. protected $batchSize;
  16. /**
  17. * @param int $batchSize Size of each batch
  18. */
  19. public function __construct($batchSize = 50)
  20. {
  21. $this->batchSize = $batchSize;
  22. }
  23. /**
  24. * Creates batches by grouping commands by their associated client
  25. * {@inheritdoc}
  26. */
  27. public function createBatches(\SplQueue $queue)
  28. {
  29. $groups = new \SplObjectStorage();
  30. foreach ($queue as $item) {
  31. if (!$item instanceof CommandInterface) {
  32. throw new InvalidArgumentException('All items must implement Guzzle\Service\Command\CommandInterface');
  33. }
  34. $client = $item->getClient();
  35. if (!$groups->contains($client)) {
  36. $groups->attach($client, new \ArrayObject(array($item)));
  37. } else {
  38. $groups[$client]->append($item);
  39. }
  40. }
  41. $batches = array();
  42. foreach ($groups as $batch) {
  43. $batches = array_merge($batches, array_chunk($groups[$batch]->getArrayCopy(), $this->batchSize));
  44. }
  45. return $batches;
  46. }
  47. public function transfer(array $batch)
  48. {
  49. if (empty($batch)) {
  50. return;
  51. }
  52. // Get the client of the first found command
  53. $client = reset($batch)->getClient();
  54. // Keep a list of all commands with invalid clients
  55. $invalid = array_filter($batch, function ($command) use ($client) {
  56. return $command->getClient() !== $client;
  57. });
  58. if (!empty($invalid)) {
  59. throw new InconsistentClientTransferException($invalid);
  60. }
  61. $client->execute($batch);
  62. }
  63. }