Skip to content

Commit 8e73980

Browse files
committed
Remove configurator getters and add shortcut for retrying Doctrine transactions exceptions
1 parent dd58655 commit 8e73980

File tree

6 files changed

+26
-111
lines changed

6 files changed

+26
-111
lines changed

README.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,17 +26,17 @@ $callableThatMightFail = function (int $arg1, int $arg2): int {
2626

2727
// Allows you to call the callable with parameters and retry its execution in case an exception is thrown.
2828
// You can access the return value of the callable (3 in this case).
29-
$returnValue = Retry::call($callableThatMightFail, 1, 2);
29+
$returnValue = Retry::configure()->call($callableThatMightFail, 1, 2);
3030

3131
// By default:
3232
// - The callable is retried twice (i.e. max three executions). If it still fails, the last error is rethrown.
33-
// - Retries have a 300 milliseconds delay between them.
33+
// - Retries have a no delay between them.
3434
// - Every \Throwable will trigger the retry logic, i.e. both \Exception and \Error.
3535
// You can adjust the retry logic like this:
3636
$retryingCallable = Retry::configure()
37-
->setMaxRetries(5)
38-
->setDelayInMs(100)
39-
->setRetryableExceptions(\RuntimeException::class) // other failures like \TypeError will not be retried
37+
->maxRetries(5)
38+
->delayInMs(100)
39+
->retryOnSpecificExceptions(\RuntimeException::class) // other failures like \TypeError will not be retried
4040
->decorate($callableThatMightFail)
4141
;
4242
$returnValue = $retryingCallable(1, 2);

src/Retry.php

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
namespace Tobion\Retry;
44

5+
use Doctrine\DBAL\Exception\RetryableException;
6+
57
/**
68
* Simple retry entry point providing shortcuts.
79
*
@@ -18,23 +20,17 @@ public static function configure(): RetryConfigurator
1820
}
1921

2022
/**
21-
* Returns a callable that decorates the given operation that should be retried on failure.
22-
*/
23-
public static function decorate(callable $callable): RetryingCallable
24-
{
25-
return (new RetryConfigurator())->decorate($callable);
26-
}
27-
28-
/**
29-
* Executes the passed callable and its arguments with the default retry behavior.
30-
*
31-
* @see RetryConfigurator
23+
* Executes the passed callable and its arguments with the a preconfigured retry behavior suitable for Doctrine database transactions.
3224
*
3325
* @return mixed The return value of the passed callable
3426
*/
35-
public static function call(callable $callable, ...$arguments)
27+
public static function onDoctrineExceptionWith2Retries300MsDelay(callable $callable, ...$arguments)
3628
{
37-
return (new RetryConfigurator())->call($callable, ...$arguments);
29+
return self::configure()
30+
->maxRetries(2)
31+
->delayInMs(300)
32+
->retryOnSpecificExceptions(RetryableException::class)
33+
->call($callable, ...$arguments);
3834
}
3935

4036
/**

src/RetryConfigurator.php

Lines changed: 9 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
*
1313
* @author Tobias Schultze <http://tobion.de>
1414
*/
15-
class RetryConfigurator
15+
final class RetryConfigurator
1616
{
1717
/**
1818
* @var string[]
@@ -27,20 +27,18 @@ class RetryConfigurator
2727
/**
2828
* @var int
2929
*/
30-
private $delayInMs;
30+
private $delayInMs = 0;
3131

3232
/**
3333
* Configures the retry logic. By default:
3434
*
3535
* - The callable is retried twice (i.e. max three executions). If it still fails, the last error is rethrown.
36-
* - Retries have a 300 milliseconds delay between them.
37-
* - Every \Throwable will trigger the retry logic, i.e. both exceptions and errors.
36+
* - Retries have a no delay between them.
37+
* - Every \Throwable will trigger the retry logic, i.e. both \Exception and \Error.
3838
*/
39-
public function __construct(int $maxRetries = 2, int $delayInMs = 300, string $exceptionToRetry = \Throwable::class)
39+
public function __construct(int $maxRetries = 2)
4040
{
4141
$this->maxRetries = $maxRetries;
42-
$this->delayInMs = $delayInMs;
43-
$this->setRetryableExceptions($exceptionToRetry);
4442
}
4543

4644
/**
@@ -53,7 +51,7 @@ public function __construct(int $maxRetries = 2, int $delayInMs = 300, string $e
5351
*
5452
* @return $this
5553
*/
56-
public function setRetryableExceptions(string $exceptionClass, string ...$moreExceptionClasses): self
54+
public function retryOnSpecificExceptions(string $exceptionClass, string ...$moreExceptionClasses): self
5755
{
5856
array_unshift($moreExceptionClasses, $exceptionClass);
5957
$this->retryableExceptionClasses = $moreExceptionClasses;
@@ -66,7 +64,7 @@ public function setRetryableExceptions(string $exceptionClass, string ...$moreEx
6664
*
6765
* @return $this
6866
*/
69-
public function setMaxRetries(int $maxRetries): self
67+
public function maxRetries(int $maxRetries): self
7068
{
7169
$this->maxRetries = $maxRetries;
7270

@@ -80,41 +78,13 @@ public function setMaxRetries(int $maxRetries): self
8078
*
8179
* @return $this
8280
*/
83-
public function setDelayInMs(int $milliseconds): self
81+
public function delayInMs(int $milliseconds): self
8482
{
8583
$this->delayInMs = $milliseconds;
8684

8785
return $this;
8886
}
8987

90-
/**
91-
* Returns the exception classes/interfaces to catch and retry on.
92-
*
93-
* If empty, every exception will trigger the retry logic.
94-
*
95-
* @return string[]
96-
*/
97-
public function getRetryableExceptions(): array
98-
{
99-
return $this->retryableExceptionClasses;
100-
}
101-
102-
/**
103-
* Returns the maximum number of retries.
104-
*/
105-
public function getMaxRetries(): int
106-
{
107-
return $this->maxRetries;
108-
}
109-
110-
/**
111-
* Returns the delay between retries in milliseconds.
112-
*/
113-
public function getDelayInMs(): int
114-
{
115-
return $this->delayInMs;
116-
}
117-
11888
/**
11989
* Returns a callable that decorates the given operation that should be retried on failure.
12090
*/
@@ -123,7 +93,7 @@ public function decorate(callable $operation): RetryingCallable
12393
$handlers = [];
12494

12595
// we can skip the handler in this default case
126-
if ([\Throwable::class] !== $this->retryableExceptionClasses) {
96+
if ([] !== $this->retryableExceptionClasses && [\Throwable::class] !== $this->retryableExceptionClasses) {
12797
$handlers[] = new RethrowNonRetryableExceptions(...$this->retryableExceptionClasses);
12898
}
12999

tests/RetryConfiguratorTest.php

Lines changed: 0 additions & 41 deletions
This file was deleted.

tests/RetryFunctionalityTest.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ public function testRetrySucceeds(): void
4242
public function testRetrySucceedsWithTwoRetryableExceptions(): void
4343
{
4444
$retry = (new RetryConfigurator(4))
45-
->setRetryableExceptions(TestExceptionToRetry::class,TestDifferentException::class)
45+
->retryOnSpecificExceptions(TestExceptionToRetry::class,TestDifferentException::class)
4646
->decorate([new TestExamplesToRetry(4), 'useTwoExceptions'])
4747
;
4848

@@ -65,7 +65,7 @@ public function testRetryFailsAfterMaxRetries(): void
6565

6666
public function testNoRetryWhenNotRetryableError(): void
6767
{
68-
$retry = (new RetryConfigurator(10, 300, TestExceptionToRetry::class))->decorate(
68+
$retry = (new RetryConfigurator(10))->retryOnSpecificExceptions(TestExceptionToRetry::class)->decorate(
6969
[new TestExamplesToRetry(), 'retryableErrorFollowedByOtherError']
7070
);
7171

@@ -82,7 +82,7 @@ public function testRetryDelays(): void
8282
{
8383
$start = microtime(true);
8484

85-
$returnValue = (new RetryConfigurator(2, 500))->call($this->getCallable(2));
85+
$returnValue = (new RetryConfigurator(2))->delayInMs(500)->call($this->getCallable(2));
8686

8787
$elapsedTimeInMs = (microtime(true) - $start) * 1000;
8888

tests/RetryTest.php

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,4 @@ public function testConfigure(): void
1313
{
1414
$this->assertInstanceOf(RetryConfigurator::class, Retry::configure());
1515
}
16-
17-
public function testDecorate(): void
18-
{
19-
$this->assertInstanceOf(RetryingCallable::class, Retry::decorate(function () { return 42; }));
20-
}
21-
22-
public function testCallPassesOnArgumentsAndReturnsCallableReturnValue(): void
23-
{
24-
$this->assertSame(42, Retry::call(function (int $arg1, int $arg2) { return $arg1 + $arg2; }, 40, 2));
25-
}
2616
}

0 commit comments

Comments
 (0)