1: <?php
2:
3: namespace Guzzle\Batch;
4:
5: use Guzzle\Common\Exception\InvalidArgumentException;
6: use Guzzle\Common\Exception\RuntimeException;
7:
8: /**
9: * Builder used to create custom batch objects
10: */
11: class BatchBuilder
12: {
13: /**
14: * @var bool Whether or not the batch should automatically flush
15: */
16: protected $autoFlush = false;
17:
18: /**
19: * @var bool Whether or not to maintain a batch history
20: */
21: protected $history = false;
22:
23: /**
24: * @var bool Whether or not to buffer exceptions encountered in transfer
25: */
26: protected $exceptionBuffering = false;
27:
28: /**
29: * @var mixed Callable to invoke each time a flush completes
30: */
31: protected $afterFlush;
32:
33: /**
34: * @var BatchTransferInterface Object used to transfer items in the queue
35: */
36: protected $transferStrategy;
37:
38: /**
39: * @var BatchDivisorInterface Object used to divide the queue into batches
40: */
41: protected $divisorStrategy;
42:
43: /**
44: * @var array of Mapped transfer strategies by handle name
45: */
46: protected static $mapping = array(
47: 'request' => 'Guzzle\Batch\BatchRequestTransfer',
48: 'command' => 'Guzzle\Batch\BatchCommandTransfer'
49: );
50:
51: /**
52: * Create a new instance of the BatchBuilder
53: *
54: * @return BatchBuilder
55: */
56: public static function factory()
57: {
58: return new self();
59: }
60:
61: /**
62: * Automatically flush the batch when the size of the queue reaches a certain threshold. Adds {@see FlushingBatch}.
63: *
64: * @param $threshold Number of items to allow in the queue before a flush
65: *
66: * @return BatchBuilder
67: */
68: public function autoFlushAt($threshold)
69: {
70: $this->autoFlush = $threshold;
71:
72: return $this;
73: }
74:
75: /**
76: * Maintain a history of all items that have been transferred using the batch. Adds {@see HistoryBatch}.
77: *
78: * @return BatchBuilder
79: */
80: public function keepHistory()
81: {
82: $this->history = true;
83:
84: return $this;
85: }
86:
87: /**
88: * Buffer exceptions thrown during transfer so that you can transfer as much as possible, and after a transfer
89: * completes, inspect each exception that was thrown. Enables the {@see ExceptionBufferingBatch} decorator.
90: *
91: * @return BatchBuilder
92: */
93: public function bufferExceptions()
94: {
95: $this->exceptionBuffering = true;
96:
97: return $this;
98: }
99:
100: /**
101: * Notify a callable each time a batch flush completes. Enables the {@see NotifyingBatch} decorator.
102: *
103: * @param mixed $callable Callable function to notify
104: *
105: * @return BatchBuilder
106: * @throws InvalidArgumentException if the argument is not callable
107: */
108: public function notify($callable)
109: {
110: $this->afterFlush = $callable;
111:
112: return $this;
113: }
114:
115: /**
116: * Configures the batch to transfer batches of requests. Associates a {@see \Guzzle\Http\BatchRequestTransfer}
117: * object as both the transfer and divisor strategy.
118: *
119: * @param int $batchSize Batch size for each batch of requests
120: *
121: * @return BatchBuilder
122: */
123: public function transferRequests($batchSize = 50)
124: {
125: $className = self::$mapping['request'];
126: $this->transferStrategy = new $className($batchSize);
127: $this->divisorStrategy = $this->transferStrategy;
128:
129: return $this;
130: }
131:
132: /**
133: * Configures the batch to transfer batches commands. Associates as
134: * {@see \Guzzle\Service\Command\BatchCommandTransfer} as both the transfer and divisor strategy.
135: *
136: * @param int $batchSize Batch size for each batch of commands
137: *
138: * @return BatchBuilder
139: */
140: public function transferCommands($batchSize = 50)
141: {
142: $className = self::$mapping['command'];
143: $this->transferStrategy = new $className($batchSize);
144: $this->divisorStrategy = $this->transferStrategy;
145:
146: return $this;
147: }
148:
149: /**
150: * Specify the strategy used to divide the queue into an array of batches
151: *
152: * @param BatchDivisorInterface $divisorStrategy Strategy used to divide a batch queue into batches
153: *
154: * @return BatchBuilder
155: */
156: public function createBatchesWith(BatchDivisorInterface $divisorStrategy)
157: {
158: $this->divisorStrategy = $divisorStrategy;
159:
160: return $this;
161: }
162:
163: /**
164: * Specify the strategy used to transport the items when flush is called
165: *
166: * @param BatchTransferInterface $transferStrategy How items are transferred
167: *
168: * @return BatchBuilder
169: */
170: public function transferWith(BatchTransferInterface $transferStrategy)
171: {
172: $this->transferStrategy = $transferStrategy;
173:
174: return $this;
175: }
176:
177: /**
178: * Create and return the instantiated batch
179: *
180: * @return BatchInterface
181: * @throws RuntimeException if no transfer strategy has been specified
182: */
183: public function build()
184: {
185: if (!$this->transferStrategy) {
186: throw new RuntimeException('No transfer strategy has been specified');
187: }
188:
189: if (!$this->divisorStrategy) {
190: throw new RuntimeException('No divisor strategy has been specified');
191: }
192:
193: $batch = new Batch($this->transferStrategy, $this->divisorStrategy);
194:
195: if ($this->exceptionBuffering) {
196: $batch = new ExceptionBufferingBatch($batch);
197: }
198:
199: if ($this->afterFlush) {
200: $batch = new NotifyingBatch($batch, $this->afterFlush);
201: }
202:
203: if ($this->autoFlush) {
204: $batch = new FlushingBatch($batch, $this->autoFlush);
205: }
206:
207: if ($this->history) {
208: $batch = new HistoryBatch($batch);
209: }
210:
211: return $batch;
212: }
213: }
214: