diff --git a/src/infrastructure/daemon/PhabricatorDaemon.php b/src/infrastructure/daemon/PhabricatorDaemon.php --- a/src/infrastructure/daemon/PhabricatorDaemon.php +++ b/src/infrastructure/daemon/PhabricatorDaemon.php @@ -11,7 +11,7 @@ } protected function willSleep($duration) { - LiskDAO::closeAllConnections(); + LiskDAO::closeInactiveConnections(15); return; } diff --git a/src/infrastructure/storage/lisk/LiskDAO.php b/src/infrastructure/storage/lisk/LiskDAO.php --- a/src/infrastructure/storage/lisk/LiskDAO.php +++ b/src/infrastructure/storage/lisk/LiskDAO.php @@ -1621,10 +1621,55 @@ return (bool)self::$transactionIsolationLevel; } + /** + * Close any connections with no recent activity. + * + * Long-running processes can use this method to clean up connections which + * have not been used recently. + * + * @param int Close connections with no activity for this many seconds. + * @return void + */ + public static function closeInactiveConnections($idle_window) { + $connections = self::$connections; + + $now = PhabricatorTime::getNow(); + foreach ($connections as $key => $connection) { + $last_active = $connection->getLastActiveEpoch(); + + $idle_duration = ($now - $last_active); + if ($idle_duration <= $idle_window) { + continue; + } + + self::closeConnection($key); + } + } + + public static function closeAllConnections() { - self::$connections = array(); + $connections = self::$connections; + + foreach ($connections as $key => $connection) { + self::closeConnection($key); + } + } + + private static function closeConnection($key) { + if (empty(self::$connections[$key])) { + throw new Exception( + pht( + 'No database connection with connection key "%s" exists!', + $key)); + } + + $connection = self::$connections[$key]; + unset(self::$connections[$key]); + + $connection->close(); } + /* -( Utilities )---------------------------------------------------------- */