Passed
Pull Request — master (#980)
by butschster
08:08
created

RetryPolicy   A

Complexity

Total Complexity 11

Size/Duplication

Total Lines 65
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 11
eloc 22
c 1
b 0
f 0
dl 0
loc 65
ccs 24
cts 24
cp 1
rs 10

3 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 22 4
A isRetryable() 0 11 6
A getDelay() 0 3 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Spiral\Queue;
6
7
use Spiral\Queue\Exception\InvalidArgumentException;
8
use Spiral\Queue\Exception\JobException;
9
use Spiral\Queue\Exception\RetryableExceptionInterface;
10
11
final class RetryPolicy implements RetryPolicyInterface
12
{
13
    /**
14
     * @var positive-int|0
0 ignored issues
show
Documentation Bug introduced by
The doc comment positive-int|0 at position 0 could not be parsed: Unknown type name 'positive-int' at position 0 in positive-int|0.
Loading history...
15
     */
16
    private int $maxAttempts;
17
18
    /**
19
     * @var positive-int|0
0 ignored issues
show
Documentation Bug introduced by
The doc comment positive-int|0 at position 0 could not be parsed: Unknown type name 'positive-int' at position 0 in positive-int|0.
Loading history...
20
     */
21
    private int $delay;
22
23
    private float $multiplier;
24
25
    /**
26
     * @throws InvalidArgumentException
27
     */
28 16
    public function __construct(int $maxAttempts, int $delay, float $multiplier = 1)
29
    {
30 16
        if ($maxAttempts < 0) {
31 1
            throw new InvalidArgumentException(
32 1
                \sprintf('Maximum attempts must be greater than or equal to zero: `%s` given.', $maxAttempts)
33 1
            );
34
        }
35 15
        $this->maxAttempts = $maxAttempts;
36
37 15
        if ($delay < 0) {
38 1
            throw new InvalidArgumentException(
39 1
                \sprintf('Delay must be greater than or equal to zero: `%s` given.', $delay)
40 1
            );
41
        }
42 14
        $this->delay = $delay;
43
44 14
        if ($multiplier < 1) {
45 1
            throw new InvalidArgumentException(
46 1
                \sprintf('Multiplier must be greater than zero: `%s` given.', $multiplier)
47 1
            );
48
        }
49 13
        $this->multiplier = $multiplier;
50
    }
51
52
    /**
53
     * @param positive-int|0 $attempts
0 ignored issues
show
Documentation Bug introduced by
The doc comment positive-int|0 at position 0 could not be parsed: Unknown type name 'positive-int' at position 0 in positive-int|0.
Loading history...
54
     *
55
     * @return positive-int
0 ignored issues
show
Documentation Bug introduced by
The doc comment positive-int at position 0 could not be parsed: Unknown type name 'positive-int' at position 0 in positive-int.
Loading history...
56
     */
57 6
    public function getDelay(int $attempts = 0): int
58
    {
59 6
        return (int) \ceil($this->delay * $this->multiplier ** $attempts);
60
    }
61
62
    /**
63
     * @param positive-int|0 $attempts
0 ignored issues
show
Documentation Bug introduced by
The doc comment positive-int|0 at position 0 could not be parsed: Unknown type name 'positive-int' at position 0 in positive-int|0.
Loading history...
64
     */
65 11
    public function isRetryable(\Throwable $exception, int $attempts = 0): bool
66
    {
67 11
        if ($exception instanceof JobException && $exception->getPrevious() !== null) {
68 1
            $exception = $exception->getPrevious();
69
        }
70
71 11
        if (!$exception instanceof RetryableExceptionInterface || $this->maxAttempts === 0) {
72 3
            return false;
73
        }
74
75 8
        return $exception->isRetryable() && $attempts < $this->maxAttempts;
76
    }
77
}
78