diff --git a/app/controllers/general.php b/app/controllers/general.php index db9df71341..90cb3293e6 100644 --- a/app/controllers/general.php +++ b/app/controllers/general.php @@ -21,6 +21,7 @@ use Appwrite\Utopia\Response\Filters\V18 as ResponseV18; use Appwrite\Utopia\View; use Executor\Executor; use MaxMind\Db\Reader; +use Swoole\Database\DetectsLostConnections; use Swoole\Http\Request as SwooleRequest; use Utopia\App; use Utopia\CLI\Console; @@ -28,6 +29,7 @@ use Utopia\Config\Config; use Utopia\Database\Database; use Utopia\Database\DateTime; use Utopia\Database\Document; +use Utopia\Database\Exception as DatabaseException; use Utopia\Database\Helpers\ID; use Utopia\Database\Query; use Utopia\Database\Validator\Authorization; @@ -38,6 +40,7 @@ use Utopia\Logger\Adapter\Sentry; use Utopia\Logger\Log; use Utopia\Logger\Log\User; use Utopia\Logger\Logger; +use Utopia\Pools\Connection; use Utopia\System\System; use Utopia\Validator\Hostname; use Utopia\Validator\Text; @@ -746,7 +749,16 @@ App::error() ->inject('logger') ->inject('log') ->inject('queueForUsage') - ->action(function (Throwable $error, App $utopia, Request $request, Response $response, Document $project, ?Logger $logger, Log $log, Usage $queueForUsage) { + ->inject('connectionForProject') + ->action(function (Throwable $error, App $utopia, Request $request, Response $response, Document $project, ?Logger $logger, Log $log, Usage $queueForUsage, Connection $connectionForProject) { + if ( + ($error instanceof PDOException || $error instanceof DatabaseException) + && DetectsLostConnections::causedByLostConnection($error) + ) { + // Mark connection as unhealthy so it will be recycled on next reclaim. + $connectionForProject->setHealthy(false); + } + $version = System::getEnv('_APP_VERSION', 'UNKNOWN'); $route = $utopia->getRoute(); $class = \get_class($error); diff --git a/app/worker.php b/app/worker.php index 845af12efc..62882b32b1 100644 --- a/app/worker.php +++ b/app/worker.php @@ -413,7 +413,16 @@ $worker ->inject('log') ->inject('pools') ->inject('project') - ->action(function (Throwable $error, ?Logger $logger, Log $log, Group $pools, Document $project) use ($queueName) { + ->inject('connectionForProject') + ->action(function (Throwable $error, ?Logger $logger, Log $log, Group $pools, Document $project, PoolConnection $connectionForProject) use ($queueName) { + if ( + ($error instanceof PDOException || $error instanceof DatabaseException) + && DetectsLostConnections::causedByLostConnection($error) + ) { + // Mark connection as unhealthy, it will be recycled on next reclaim. + $connectionForProject->setHealthy(false); + } + $pools->reclaim(); $version = System::getEnv('_APP_VERSION', 'UNKNOWN');