Skip to content

Commit 5a800f0

Browse files
committed
In long-running processes, allows checking the database connection by pinging it, thus avoiding exceptions. Additionally, it provides the flexibility to configure the frequency of the check to be performed in the case of long-running processes.
1 parent 140ecec commit 5a800f0

File tree

1 file changed

+37
-1
lines changed

1 file changed

+37
-1
lines changed

src/Connection.php

+37-1
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
use function is_string;
4343
use function key;
4444
use function sprintf;
45+
use function time;
4546

4647
/**
4748
* A database abstraction-level connection that implements features like transaction isolation levels,
@@ -99,6 +100,12 @@ class Connection implements ServerVersionProvider
99100

100101
private SchemaManagerFactory $schemaManagerFactory;
101102

103+
private bool $isChecking = false;
104+
105+
private ?int $lastCheckedAt = null;
106+
107+
private ?int $heartbeat;
108+
102109
/**
103110
* Initializes a new instance of the Connection class.
104111
*
@@ -115,6 +122,8 @@ public function __construct(
115122
protected Driver $driver,
116123
?Configuration $config = null,
117124
) {
125+
$this->heartbeat = $params['check_connection_frequency'] ?? null;
126+
118127
$this->_config = $config ?? new Configuration();
119128
$this->params = $params;
120129
$this->autoCommit = $this->_config->getAutoCommit();
@@ -210,7 +219,23 @@ public function createExpressionBuilder(): ExpressionBuilder
210219
protected function connect(): DriverConnection
211220
{
212221
if ($this->_conn !== null) {
213-
return $this->_conn;
222+
$isTimeToCheck = $this->lastCheckedAt === null || time() - $this->lastCheckedAt >= $this->heartbeat;
223+
$noCheckNeeded = $this->heartbeat === null || $this->isChecking;
224+
225+
if ($noCheckNeeded || ! $isTimeToCheck) {
226+
return $this->_conn;
227+
}
228+
229+
$this->isChecking = true;
230+
231+
$isAvailable = $this->reconnectOnFailure();
232+
233+
$this->lastCheckedAt = time();
234+
$this->isChecking = false;
235+
236+
if ($isAvailable) {
237+
return $this->_conn;
238+
}
214239
}
215240

216241
try {
@@ -1371,4 +1396,15 @@ private function handleDriverException(
13711396

13721397
return $exception;
13731398
}
1399+
1400+
private function reconnectOnFailure(): bool
1401+
{
1402+
try {
1403+
$this->executeQuery($this->getDatabasePlatform($this)->getDummySelectSQL());
1404+
1405+
return true;
1406+
} catch (ConnectionLost) {
1407+
return false;
1408+
}
1409+
}
13741410
}

0 commit comments

Comments
 (0)