/** * {@inheritdoc} */ public function run(Operation $operation) { $this->buffer->add($operation); while (null !== ($operation = $this->buffer->current())) { $this->runner->run($operation); $this->buffer->pop(); } }
/** * Runs the buffered operations. * * It returns an array of results. * * @return mixed[] */ public function runBufferedOperations() { $results = []; while (null !== ($operation = $this->buffer->current())) { $results[] = $this->runner->run($operation); $this->buffer->pop(); } return $results; }
/** * {@inheritdoc} */ public function run(Operation $operation) { $identifier = $this->identifierStrategy->getOperationIdentifier($operation); if ($this->rateLimit->hasReachedLimit($identifier)) { $this->waiter->wait($this->rateLimit->getTicksBeforeUnderLimit($identifier)); } $this->rateLimit->tick($identifier); return $this->runner->run($operation); }
/** * {@inheritdoc} */ public function run(Operation $operation) { try { return $this->runner->run($operation); } catch (\Exception $e) { try { $this->waitStrategy->wait(); } catch (WaiterException $waiterException) { throw $e; } return $this->run($operation); } }
/** * {@inheritdoc} */ public function run(Operation $operation) { try { $result = $this->decoratedOperationRunner->run($operation); $this->metricPublisher->publish([new Metric($this->namespace . '.success', 1, Metric::TYPE_INCREMENT)]); return $result; } catch (\Exception $e) { // Will be re-thrown later } catch (\Throwable $e) { // Will be re-thrown later } $this->metricPublisher->publish([new Metric($this->namespace . '.failure', 1, Metric::TYPE_INCREMENT)]); throw $e; }
function it_keeps_the_operation_in_the_buffer_if_it_fails(OperationBuffer $buffer, OperationRunner $runner, Operation $operation) { $runner->run($operation)->willThrow(new \RuntimeException('Unable to run the operation')); $buffer->current()->willReturn($operation); $this->shouldThrow(\RuntimeException::class)->duringRun($operation); $buffer->pop()->shouldNotBeCalled(); }
function it_publish_a_failure_metric_and_rethrow_an_exception(OperationRunner $runner, MetricPublisher $publisher, Operation $operation) { $e = new \InvalidArgumentException(); $runner->run($operation)->willThrow($e); $publisher->publish([new Metric('my_namespace.failure', 1, Metric::TYPE_INCREMENT)])->shouldBeCalled(); $this->shouldThrow($e)->during('run', [$operation]); }
function it_returns_a_placeholder_response_if_it_fails(OperationRunner $decoratedRunner, Operation $operation, PlaceholderResponseResolver $placeholderResponseResolver) { $exception = new \Exception(); $decoratedRunner->run($operation)->willThrow($exception); $placeholderResponseResolver->createResponse($operation, $exception)->shouldBeCalled()->willReturn(''); $this->run($operation)->shouldBe(''); }
function it_should_throw_the_original_exception_if_the_wait_fails(OperationRunner $runner, Waiter $waiter, Operation $operation) { $runner->run($operation)->will(function () use($operation) { throw new \RuntimeException('Operation failed'); }); $waiter->wait()->willThrow(new WaiterException('Retried to many times')); $this->shouldThrow(\RuntimeException::class)->duringRun($operation); }
function it_waits_the_number_of_required_tick_if_the_rate_limit_is_reached(OperationRunner $runner, RateLimit $rateLimit, Waiter $waiter, Operation $operation) { $rateLimit->hasReachedLimit(Argument::any())->willReturn(true); $rateLimit->getTicksBeforeUnderLimit(Argument::any())->willReturn(10); $waiter->wait(10)->shouldBeCalled(); $runner->run($operation)->shouldBeCalled(); $rateLimit->tick(Argument::any())->shouldBeCalled(); $this->run($operation); }
/** * {@inheritdoc} */ public function run(Operation $operation) { try { return $this->decoratedRunner->run($operation); } catch (\Exception $e) { // Handled later } catch (\Throwable $e) { // Handled later } if (!$this->catcherVoter->shouldCatchThrowable($e)) { throw $e; } $placeholder = $this->placeholderResponseResolver->createResponse($operation, $e); if (null !== $this->logger) { $this->logger->warning('An operation exception was replaced by a placeholder', ['operation' => $operation, 'placeholder' => $placeholder]); } return $placeholder; }
function it_runs_the_publish_via_a_callback_operation(MetricPublisher $decoratedPublisher, OperationRunner $operationRunner) { $operationRunner->run(Argument::that(function ($operation) { if (!$operation instanceof Callback) { return false; } $operation->call(); return true; }))->shouldBeCalled(); $metrics = [new Metric('name', 'foo')]; $decoratedPublisher->publish($metrics)->shouldBeCalled(); $this->publish($metrics); }
/** * @param Operation $operation * * @return mixed */ private function runOperation(Operation $operation) { try { return $this->runner->run($operation); } catch (\Throwable $e) { // treated below } catch (\Exception $e) { // treated below } // @todo keep only inner if once ExceptionCatcher is gone if ($this->exceptionCatcherVoter instanceof ThrowableCatcherVoter) { if (!$this->exceptionCatcherVoter->shouldCatchThrowable($e)) { throw $e; } } elseif (!$this->exceptionCatcherVoter->shouldCatch($e)) { throw $e; } try { $this->waitStrategy->wait(); } catch (WaiterException $waiterException) { throw $e; } return $this->runOperation($operation); }
/** * {@inheritdoc} */ public function publish(array $metrics) { return $this->operationRunner->run(new Callback(function () use($metrics) { return $this->decoratedPublisher->publish($metrics); })); }