Passed
Push — master ( 53fb0a...569237 )
by Eugene
03:14
created

RetryMiddleware::linear()   A

Complexity

Conditions 2
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 2
c 1
b 0
f 0
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
cc 2
nc 1
nop 2
crap 2
1
<?php
2
3
/**
4
 * This file is part of the Tarantool Client package.
5
 *
6
 * (c) Eugene Leonovich <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
declare(strict_types=1);
13
14
namespace Tarantool\Client\Middleware;
15
16
use Tarantool\Client\Exception\UnexpectedResponse;
17
use Tarantool\Client\Handler\Handler;
18
use Tarantool\Client\Request\Request;
19
use Tarantool\Client\Response;
20
21
final class RetryMiddleware implements Middleware
22
{
23
    public const DEFAULT_MAX_RETRIES = 3;
24
25
    private $getDelayMs;
26
27 10
    private function __construct(\Closure $getDelayMs)
28
    {
29 10
        $this->getDelayMs = $getDelayMs;
30 10
    }
31
32
    public static function constant(int $maxRetries = self::DEFAULT_MAX_RETRIES, int $intervalMs = 100) : self
33
    {
34
        return new self(static function (int $retries) use ($maxRetries, $intervalMs) {
35
            return $retries > $maxRetries ? null : $intervalMs;
36
        });
37
    }
38
39
    public static function exponential(int $maxRetries = self::DEFAULT_MAX_RETRIES, int $baseMs = 100) : self
40
    {
41
        return new self(static function (int $retries) use ($maxRetries, $baseMs) {
42
            return $retries > $maxRetries ? null : $baseMs ** $retries;
43
        });
44
    }
45
46 6
    public static function linear(int $maxRetries = self::DEFAULT_MAX_RETRIES, int $differenceMs = 100) : self
47
    {
48
        return new self(static function (int $retries) use ($maxRetries, $differenceMs) {
49 4
            return $retries > $maxRetries ? null : $differenceMs * $retries;
50 6
        });
51
    }
52
53 4
    public static function custom(\Closure $getDelayMs) : self
54
    {
55
        return new self(static function (int $retries) use ($getDelayMs) : ?int {
56 4
            return $getDelayMs($retries);
57 4
        });
58
    }
59
60 10
    public function process(Request $request, Handler $handler) : Response
61
    {
62 10
        $retries = 0;
63
64
        do {
65
            try {
66 10
                return $handler->handle($request);
67 10
            } catch (UnexpectedResponse $e) {
68 2
                break;
69 8
            } catch (\Throwable $e) {
70 8
                if (null === $delayMs = ($this->getDelayMs)(++$retries)) {
71 4
                    break;
72
                }
73 8
                \usleep($delayMs * 1000);
74
            }
75 8
        } while (true);
76
77 6
        throw $e;
78
    }
79
}
80