42
42
use function is_string ;
43
43
use function key ;
44
44
use function sprintf ;
45
+ use function time ;
45
46
46
47
/**
47
48
* A database abstraction-level connection that implements features like transaction isolation levels,
@@ -99,6 +100,12 @@ class Connection implements ServerVersionProvider
99
100
100
101
private SchemaManagerFactory $ schemaManagerFactory ;
101
102
103
+ private bool $ isChecking = false ;
104
+
105
+ private ?int $ lastCheckedAt = null ;
106
+
107
+ private ?int $ heartbeat ;
108
+
102
109
/**
103
110
* Initializes a new instance of the Connection class.
104
111
*
@@ -115,6 +122,8 @@ public function __construct(
115
122
protected Driver $ driver ,
116
123
?Configuration $ config = null ,
117
124
) {
125
+ $ this ->heartbeat = $ params ['check_connection_frequency ' ] ?? null ;
126
+
118
127
$ this ->_config = $ config ?? new Configuration ();
119
128
$ this ->params = $ params ;
120
129
$ this ->autoCommit = $ this ->_config ->getAutoCommit ();
@@ -210,7 +219,23 @@ public function createExpressionBuilder(): ExpressionBuilder
210
219
protected function connect (): DriverConnection
211
220
{
212
221
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
+ }
214
239
}
215
240
216
241
try {
@@ -1371,4 +1396,15 @@ private function handleDriverException(
1371
1396
1372
1397
return $ exception ;
1373
1398
}
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
+ }
1374
1410
}
0 commit comments