RetryExecutor::tryQuery()   B
last analyzed

Complexity

Conditions 3
Paths 1

Size

Total Lines 28
Code Lines 16

Duplication

Lines 0
Ratio 0 %
Metric Value
dl 0
loc 28
rs 8.8571
cc 3
eloc 16
nc 1
nop 4
1
<?php
2
3
namespace Thruster\Component\Dns;
4
5
use Thruster\Component\Dns\Exception\TimeoutException;
6
use Thruster\Component\Promise\Deferred;
7
use Thruster\Component\Promise\PromiseInterface;
8
9
/**
10
 * Class RetryExecutor
11
 *
12
 * @package Thruster\Component\Dns
13
 * @author  Aurimas Niekis <[email protected]>
14
 */
15
class RetryExecutor implements ExecutorInterface
16
{
17
    /**
18
     * @var ExecutorInterface
19
     */
20
    private $executor;
21
22
    /**
23
     * @var int
24
     */
25
    private $retries;
26
27
    public function __construct(ExecutorInterface $executor, int $retries = 2)
28
    {
29
        $this->executor = $executor;
30
        $this->retries  = $retries;
31
    }
32
33
    public function query(string $nameServer, Query $query) : PromiseInterface
34
    {
35
        $deferred = new Deferred();
36
37
        $this->tryQuery($nameServer, $query, $this->retries, $deferred);
38
39
        return $deferred->promise();
40
    }
41
42
    public function tryQuery(string $nameServer, Query $query, int $retries, Deferred $deferred)
43
    {
44
        $errorCallback = function ($error) use ($nameServer, $query, $retries, $deferred) {
45
            if (false === ($error instanceof TimeoutException)) {
46
                $deferred->reject($error);
47
48
                return;
49
            }
50
51
            if (0 >= $retries) {
52
                $error = new \RuntimeException(
53
                    sprintf("DNS query for %s failed: too many retries", $query->getName()),
54
                    0,
55
                    $error
56
                );
57
58
                $deferred->reject($error);
59
60
                return;
61
            }
62
63
            $this->tryQuery($nameServer, $query, $retries - 1, $deferred);
64
        };
65
66
        $this->executor
67
            ->query($nameServer, $query)
68
            ->then([$deferred, 'resolve'], $errorCallback);
69
    }
70
}
71