diff --git a/src/CircuitBreakerFactory.php b/src/CircuitBreakerFactory.php index ea04b9b..b42b6ba 100644 --- a/src/CircuitBreakerFactory.php +++ b/src/CircuitBreakerFactory.php @@ -33,17 +33,25 @@ public function __construct(array $config, StorageInterface $storage) protected static function configureOptions(OptionsResolver $options): void { - $options->setRequired(['failure_threshold', 'retry_policy', 'reset_timeout', 'maximum_timeout']); + $options->setRequired(['failure_threshold', 'retry_policy']); $options->setAllowedTypes('failure_threshold', 'int'); - $options->setAllowedTypes('reset_timeout', 'int'); - $options->setAllowedTypes('maximum_timeout', 'int'); - $options->setAllowedValues('retry_policy', ['constant', 'exponential', 'linear']); $options->setDefaults([ 'failure_threshold' => 5, - 'retry_policy' => 'exponential', - 'reset_timeout' => 60, - 'maximum_timeout' => 86400, + 'retry_policy' => function (OptionsResolver $policyResolver) { + $policyResolver->setDefaults([ + 'type' => 'exponential', + 'options' => function (OptionsResolver $optionsResolver) { + $optionsResolver->setDefaults([ + 'reset_timeout' => 60, + 'maximum_timeout' => 86400, + ]); + $optionsResolver->setAllowedTypes('reset_timeout', 'int'); + $optionsResolver->setAllowedTypes('maximum_timeout', 'int'); + }, + ]); + $policyResolver->setAllowedValues('type', ['constant', 'exponential', 'linear']); + } ]); } @@ -54,13 +62,15 @@ public function create(string $name): CircuitBreaker private function createRetryPolicy(): RetryPolicyInterface { - switch ($this->config['retry_policy']) { + $options = $this->config['retry_policy']['options']; + + switch ($this->config['retry_policy']['type']) { case 'constant': - return new ConstantRetryPolicy($this->config['reset_timeout']); + return new ConstantRetryPolicy($options['reset_timeout']); case 'exponential': - return new ExponentialRetryPolicy($this->config['reset_timeout'], $this->config['maximum_timeout']); + return new ExponentialRetryPolicy($options['reset_timeout'], $options['maximum_timeout']); case 'linear': - return new LinearRetryPolicy($this->config['reset_timeout']); + return new LinearRetryPolicy($options['reset_timeout']); default: throw new \LogicException(sprintf('Retry policy "%s" does not exists, it must be one of "constant", "exponential", "linear".', $this->config['retry_policy'])); } diff --git a/tests/CircuitBreakerFactoryTest.php b/tests/CircuitBreakerFactoryTest.php index 41919fd..2f219ed 100644 --- a/tests/CircuitBreakerFactoryTest.php +++ b/tests/CircuitBreakerFactoryTest.php @@ -39,33 +39,35 @@ public function factoryConfigProvider(): iterable ]]; yield [[ - 'reset_timeout' => 4000, + 'retry_policy' => ['options' => ['reset_timeout' => 4000]], ]]; yield [[ - 'reset_timeout' => 4000, - 'maximum_timeout' => 50000, + 'retry_policy' => ['options' => [ + 'reset_timeout' => 4000, + 'maximum_timeout' => 50000, + ]], ]]; yield [[ - 'retry_policy' => 'constant', + 'retry_policy' => ['type' => 'constant'], ]]; yield [[ - 'retry_policy' => 'exponential', + 'retry_policy' => ['type' => 'exponential'], ]]; yield [[ - 'retry_policy' => 'linear', + 'retry_policy' => ['type' => 'linear'], ]]; } public function testInvalidRetryPolicy(): void { $this->expectException(InvalidOptionsException::class); - $this->expectExceptionMessage('The option "retry_policy" with value "nonexistent" is invalid. Accepted values are: "constant", "exponential", "linear".'); + $this->expectExceptionMessage('The option "type" with value "nonexistent" is invalid. Accepted values are: "constant", "exponential", "linear".'); - $factory = new CircuitBreakerFactory(['retry_policy' => 'nonexistent'], new InMemoryStorage()); + $factory = new CircuitBreakerFactory(['retry_policy' => ['type' => 'nonexistent']], new InMemoryStorage()); $factory->create('name'); }