/** * Upload the source asynchronously using multipart upload operations. * * @return PromiseInterface */ public function promise() { if ($this->promise) { return $this->promise; } return $this->promise = Promise\coroutine(function () { // Initiate the upload. if ($this->state->isCompleted()) { throw new \LogicException('This multipart upload has already ' . 'been completed or aborted.'); } elseif (!$this->state->isInitiated()) { $result = (yield $this->execCommand('initiate', $this->getInitiateParams())); $this->state->setUploadId($this->info['id']['upload_id'], $result[$this->info['id']['upload_id']]); $this->state->setStatus(UploadState::INITIATED); } // Create a command pool from a generator that yields UploadPart // commands for each upload part. $resultHandler = $this->getResultHandler($errors); $commands = new CommandPool($this->client, $this->getUploadCommands($resultHandler), ['concurrency' => $this->config['concurrency'], 'before' => $this->config['before_upload']]); // Execute the pool of commands concurrently, and process errors. (yield $commands->promise()); if ($errors) { throw new MultipartUploadException($this->state, $errors); } // Complete the multipart upload. (yield $this->execCommand('complete', $this->getCompleteParams())); $this->state->setStatus(UploadState::COMPLETED); })->otherwise(function (\Exception $e) { // Throw errors from the operations as a specific Multipart error. if ($e instanceof AwsException) { $e = new MultipartUploadException($this->state, $e); } throw $e; }); }
/** * Flushes the batch by combining all the queued put and delete requests * into BatchWriteItem commands and executing them. Unprocessed items are * automatically re-queued. * * @param bool $untilEmpty If true, flushing will continue until the queue * is completely empty. This will make sure that * unprocessed items are all eventually sent. * * @return $this */ public function flush($untilEmpty = true) { // Send BatchWriteItem requests until the queue is empty $keepFlushing = true; while ($this->queue && $keepFlushing) { $commands = $this->prepareCommands(); $pool = new CommandPool($this->client, $commands, ['before' => $this->config['before'], 'concurrency' => $this->config['pool_size'], 'fulfilled' => function (ResultInterface $result) { // Re-queue any unprocessed items if ($result->hasKey('UnprocessedItems')) { $this->retryUnprocessed($result['UnprocessedItems']); } }, 'rejected' => function ($reason) { if ($reason instanceof AwsException) { $code = $reason->getAwsErrorCode(); if ($code === 'ProvisionedThroughputExceededException') { $this->retryUnprocessed($reason->getCommand()['RequestItems']); } elseif (is_callable($this->config['error'])) { $this->config['error']($reason); } } }]); $pool->promise()->wait(); $keepFlushing = (bool) $untilEmpty; } return $this; }