Skip to content

Commit

Permalink
Fix mysql gone away issue - #1241 #1221 #1220
Browse files Browse the repository at this point in the history
  • Loading branch information
asika32764 committed Jun 16, 2024
1 parent b5333fd commit ad72023
Show file tree
Hide file tree
Showing 6 changed files with 70 additions and 13 deletions.
27 changes: 22 additions & 5 deletions src/Driver/AbstractDriver.php
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,21 @@ public function getConnection(bool $keep = false): ConnectionInterface
return $conn;
}

public function dropConnection(?ConnectionInterface $conn = null): static
{
if ($conn) {
$conn->release();

$this->getPool()->dropConnection($conn);
} elseif ($this->connection) {
$this->getPool()->dropConnection(
$this->releaseKeptConnection()
);
}

return $this;
}

public function releaseKeptConnection(): ?ConnectionInterface
{
if ($this->connection) {
Expand Down Expand Up @@ -209,16 +224,18 @@ public function useConnection(callable $callback): mixed
return $result;
}

/**
* disconnect
*
* @return int
*/
public function disconnectAll(): int
{
return $this->getPool()->close();
}

public function disconnect(): static
{
$this->dropConnection();

return $this;
}

/**
* createStatement
*
Expand Down
40 changes: 40 additions & 0 deletions src/Driver/AbstractStatement.php
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,46 @@ public function execute(?array $params = null): static
*/
abstract protected function doExecute(?array $params = null): bool;

protected function tryExecute(\Closure $handler)
{
return $this->driver->useConnection(
function (ConnectionInterface $conn) use ($handler) {
try {
return $handler($conn);
} catch (\Exception $e) {
if (!$this->shouldReconnect($e)) {
throw $e;
}

$conn->reconnect();

return $handler($conn);
}
}
);
}

protected function shouldReconnect(\Throwable $e): bool
{
$keywords = [
'has gone away',
'lost connection',
'went away',
'connection timed out',
'operation timed out'
];

$message = strtolower($e->getMessage());

foreach ($keywords as $keyword) {
if (str_contains($message, strtolower($keyword))) {
return true;
}
}

return false;
}

/**
* @inheritDoc
*/
Expand Down
2 changes: 1 addition & 1 deletion src/Driver/Mysqli/MysqliStatement.php
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ static function ($param) {

[$query, $params] = BoundedHelper::replaceParams($this->query, '?', $params);

$this->driver->useConnection(
$this->tryExecute(
function (ConnectionInterface $conn) use ($params, $query) {
$this->conn = $conn->get();
$this->cursor = $stmt = $this->conn->prepare($query);
Expand Down
2 changes: 1 addition & 1 deletion src/Driver/Pdo/PdoStatement.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ class PdoStatement extends AbstractStatement
*/
protected function doExecute(?array $params = null): bool
{
return $this->driver->useConnection(
return $this->tryExecute(
function (ConnectionInterface $conn) use ($params) {
/** @var PDO $pdo */
$this->conn = $pdo = $conn->get();
Expand Down
10 changes: 5 additions & 5 deletions src/Driver/Pgsql/PgsqlStatement.php
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ static function ($param) {

[$query, $params] = BoundedHelper::replaceParams($this->query, '$%d', $params);

$this->driver->useConnection(
$this->tryExecute(
function (ConnectionInterface $conn) use ($params, $query) {
$this->conn = $resource = $conn->get();

Expand All @@ -60,13 +60,13 @@ function (ConnectionInterface $conn) use ($params, $query) {
}

$this->cursor = pg_execute($resource, $stname, $args);

if (!$this->cursor) {
throw new StatementException(pg_last_error());
}
}
);

if (!$this->cursor) {
throw new StatementException(pg_last_error());
}

return true;
}

Expand Down
2 changes: 1 addition & 1 deletion src/Driver/Sqlsrv/SqlsrvStatement.php
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ static function ($param) {
$args[] = &$param['value'];
}

return $this->driver->useConnection(
return $this->tryExecute(
function (ConnectionInterface $conn) use ($args, $query) {
$this->conn = $resource = $conn->get();

Expand Down

0 comments on commit ad72023

Please sign in to comment.