Failed Conditions
Pull Request — master (#43)
by
unknown
02:11
created

RetryStrategy::__destruct()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 6
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 4
nc 2
nop 0
1
<?php
2
3
namespace Ez\DbLinker\RetryStrategy;
4
5
use Exception;
6
use stdClass;
7
use Ez\DbLinker\Driver\Connection\MasterSlavesConnection;
8
use Ez\DbLinker\Driver\Connection\RetryConnection;
9
10
trait RetryStrategy
11
{
12
    private $retryLimit;
13
14
    public function __construct($retryLimit = INF)
15
    {
16
        $this->retryLimit = $retryLimit;
17
    }
18
19
    public function shouldRetry(Exception $exception, RetryConnection $connection) {
20
        if (!$this->canRetry($connection)) {
21
            return false;
22
        }
23
        $strategy = $this->errorCodeStrategy($this->errorCode($exception));
24
        $res = $this->applyStrategy($strategy, $connection);
25
        return $res;
26
    }
27
28
    public function retryLimit()
29
    {
30
        return $this->retryLimit > 0 ? (int) $this->retryLimit : 0;
31
    }
32
33
    private function canRetry(RetryConnection $connection)
34
    {
35
        return $this->retryLimit > 0 && $connection->transactionLevel() === 0;
36
    }
37
38
    private function errorCodeStrategy($errorCode)
39
    {
40
        $strategy = (object) [
41
            'retry' => true,
42
            'wait' => 0,
43
            'changeServer' => false,
44
            'reconnect' => false,
45
        ];
46
        $errorCodeStrategies = $this->errorCodeStrategies();
47
        if (array_key_exists($errorCode, $errorCodeStrategies)) {
48
            foreach ($errorCodeStrategies[$errorCode] as $behavior => $value) {
49
                $strategy->$behavior = $value;
50
            }
51
            return $strategy;
52
        }
53
        return (object) ['retry' => false];
54
    }
55
56
    private function applyStrategy(stdClass $strategy, RetryConnection $connection) {
57
        if ($strategy->retry === false || !$this->changeServer($strategy, $connection)) {
58
            return false;
59
        }
60
        sleep($strategy->wait);
61
        $this->reconnect($strategy, $connection);
62
        $this->retryLimit--;
63
        return true;
64
    }
65
66
    private function changeServer(stdClass $strategy, RetryConnection $connection)
67
    {
68
        if (!$strategy->changeServer) {
69
            return true;
70
        }
71
        $wrappedConnection = $connection->wrappedConnection();
72
        if ($wrappedConnection instanceof MasterSlavesConnection && !$wrappedConnection->isConnectedToMaster()) {
73
            $wrappedConnection->disableCurrentSlave();
74
            return true;
75
        }
76
        return false;
77
    }
78
79
    private function reconnect(stdClass $strategy, RetryConnection $connection)
80
    {
81
        if ($strategy->reconnect) {
82
            $connection->close();
83
        }
84
    }
85
86
    public function __destruct() {
87
        $wrappedConnection = $connection->wrappedConnection();
0 ignored issues
show
Bug introduced by
The variable $connection does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
Unused Code introduced by
$wrappedConnection is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
88
        if ($connection !== null) {
89
            $connection->close();
90
        }
91
    }
92
93
    protected abstract function errorCodeStrategies();
94
    protected abstract function errorCode(Exception $exception);
95
}
96