GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.

Issues (246)

PingingAndReconnectingConnection.php (1 issue)

Severity
1
<?php
2
3
declare(strict_types=1);
4
5
namespace EdmondsCommerce\DoctrineStaticMeta\EntityManager\RetryConnection;
6
7
use Doctrine\Common\EventManager;
8
use Doctrine\DBAL\Cache\QueryCacheProfile;
9
use Doctrine\DBAL\Configuration;
10
use Doctrine\DBAL\Connection;
11
use Doctrine\DBAL\DBALException;
12
use Doctrine\DBAL\Driver;
13
use ReflectionProperty;
14
use ts\Reflection\ReflectionClass;
15
16
/**
17
 * This is a connection wrapper that enables some retry functionality should the connection to the DB be lost for any
18
 * reason. Especially useful on long running processes
19
 */
20
class PingingAndReconnectingConnection extends Connection
21
{
22
    /**
23
     * How many seconds between pings
24
     *
25
     * @var float
26
     */
27
    private const PING_INTERVAL_SECONDS = 1.0;
28
29
    private const PING_FAILURE_SLEEP_SECONDS = 10;
30
31
    /** @var ReflectionProperty */
32
    private $selfReflectionNestingLevelProperty;
33
34
    /** @var float */
35
    private $pingTimer = 0;
36
37
    public function executeUpdate($query, array $params = [], array $types = [])
38
    {
39
        $args = [$query, $params, $types];
40
41
        return $this->pingBeforeMethodCall(__FUNCTION__, $args);
42
    }
43
44
    private function pingBeforeMethodCall(string $function, array $args)
45
    {
46
        $this->pingAndReconnectOnFailure();
47
48
        return parent::$function(...$args);
49
    }
50
51
    public function pingAndReconnectOnFailure(): void
52
    {
53
        if (microtime(true) < ($this->pingTimer + self::PING_INTERVAL_SECONDS)) {
54
            return;
55
        }
56
        $this->pingTimer = microtime(true);
57
        if (false === $this->ping()) {
58
            $this->close();
59
            $this->resetTransactionNestingLevel();
60
            sleep(self::PING_FAILURE_SLEEP_SECONDS);
61
            parent::connect();
62
        }
63
    }
64
65
    /**
66
     * Overriding the ping method so we explicitly call the raw unwrapped methods as required, otherwise we go into
67
     * infinite loop
68
     *
69
     * @return bool
70
     */
71
    public function ping(): bool
72
    {
73
        parent::connect();
74
75
        if ($this->_conn instanceof Driver\PingableConnection) {
76
            return $this->_conn->ping();
77
        }
78
79
        try {
80
            parent::query($this->getDatabasePlatform()->getDummySelectSQL());
81
82
            return true;
83
        } catch (DBALException $e) {
84
            return false;
85
        }
86
    }
87
88
89
    /**
90
     * This is required because beginTransaction increment _transactionNestingLevel
91
     * before the real query is executed, and results incremented also on gone away error.
92
     * This should be safe for a new established connection.
93
     */
94
    private function resetTransactionNestingLevel(): void
95
    {
96
        if (!$this->selfReflectionNestingLevelProperty instanceof ReflectionProperty) {
0 ignored issues
show
$this->selfReflectionNestingLevelProperty is always a sub-type of ReflectionProperty.
Loading history...
97
            $reflection                               = new ReflectionClass(Connection::class);
98
            $this->selfReflectionNestingLevelProperty = $reflection->getProperty('transactionNestingLevel');
99
            $this->selfReflectionNestingLevelProperty->setAccessible(true);
100
        }
101
102
        $this->selfReflectionNestingLevelProperty->setValue($this, 0);
103
    }
104
105
    public function query(...$args)
106
    {
107
        return $this->pingBeforeMethodCall(__FUNCTION__, $args);
108
    }
109
110
    public function executeQuery($query, array $params = [], $types = [], QueryCacheProfile $qcp = null)
111
    {
112
        $args = [$query, $params, $types, $qcp];
113
114
        return $this->pingBeforeMethodCall(__FUNCTION__, $args);
115
    }
116
117
    public function beginTransaction()
118
    {
119
        $this->pingBeforeMethodCall(__FUNCTION__, []);
120
    }
121
122
    /**
123
     * @param string $sql
124
     *
125
     * @return Statement
126
     */
127
    public function prepare($sql): Statement
128
    {
129
        return $this->prepareWrapped($sql);
130
    }
131
132
    /**
133
     * returns a reconnect-wrapper for Statements.
134
     *
135
     * @param string $sql
136
     *
137
     * @return Statement
138
     */
139
    protected function prepareWrapped(string $sql): Statement
140
    {
141
        $this->pingAndReconnectOnFailure();
142
143
        return new Statement($sql, $this);
144
    }
145
146
    /**
147
     * do not use, only used by Statement-class
148
     * needs to be public for access from the Statement-class.
149
     *
150
     * @param string $sql
151
     *
152
     * @return Driver\Statement
153
     * @throws DBALException
154
     *@internal
155
     *
156
     */
157
    public function prepareUnwrapped(string $sql): Driver\Statement
158
    {
159
        // returns the actual statement
160
        return parent::prepare($sql);
161
    }
162
}
163