Skip to content

Commit

Permalink
Merge pull request #41819 from nextcloud/enh/reconnect-again
Browse files Browse the repository at this point in the history
  • Loading branch information
juliusknorr authored Jan 12, 2024
2 parents b9e3e6f + 296096e commit 39dee92
Showing 1 changed file with 27 additions and 0 deletions.
27 changes: 27 additions & 0 deletions lib/private/DB/Connection.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
use Doctrine\DBAL\Connections\PrimaryReadReplicaConnection;
use Doctrine\DBAL\Driver;
use Doctrine\DBAL\Exception;
use Doctrine\DBAL\Exception\ConnectionLost;
use Doctrine\DBAL\Platforms\MySQLPlatform;
use Doctrine\DBAL\Platforms\OraclePlatform;
use Doctrine\DBAL\Platforms\SqlitePlatform;
Expand Down Expand Up @@ -78,6 +79,7 @@ class Connection extends PrimaryReadReplicaConnection {

/** @var DbDataCollector|null */
protected $dbDataCollector = null;
private array $lastConnectionCheck = [];

protected ?float $transactionActiveSince = null;

Expand Down Expand Up @@ -127,10 +129,13 @@ public function __construct(
public function connect($connectionName = null) {
try {
if ($this->_conn) {
$this->reconnectIfNeeded();
/** @psalm-suppress InternalMethod */
return parent::connect();
}

$this->lastConnectionCheck[$this->getConnectionName()] = time();

// Only trigger the event logger for the initial connect call
$eventLogger = \OC::$server->get(IEventLogger::class);
$eventLogger->start('connect:db', 'db connection opened');
Expand Down Expand Up @@ -679,4 +684,26 @@ public function rollBack() {
}
return $result;
}

private function reconnectIfNeeded(): void {
if (
!isset($this->lastConnectionCheck[$this->getConnectionName()]) ||
$this->lastConnectionCheck[$this->getConnectionName()] + 30 >= time() ||
$this->isTransactionActive()
) {
return;
}

try {
$this->_conn->query($this->getDriver()->getDatabasePlatform()->getDummySelectSQL());
$this->lastConnectionCheck[$this->getConnectionName()] = time();
} catch (ConnectionLost|\Exception $e) {
$this->logger->warning('Exception during connectivity check, closing and reconnecting', ['exception' => $e]);
$this->close();
}
}

private function getConnectionName(): string {
return $this->isConnectedToPrimary() ? 'primary' : 'replica';
}
}

0 comments on commit 39dee92

Please sign in to comment.