diff options
author | Ari Selseng <ari@selseng.net> | 2019-03-03 01:36:27 +0100 |
---|---|---|
committer | Ari Selseng <ari@selseng.net> | 2019-03-03 01:36:27 +0100 |
commit | 71a0cdceaaad76cd08f48c28d3da40d7fc8d2abf (patch) | |
tree | 6d42973762495bf32889499997a2083b5ba5528f | |
parent | 1cfa870821c92bdd6854171c8c073ed16529b6df (diff) | |
download | nextcloud-server-71a0cdceaaad76cd08f48c28d3da40d7fc8d2abf.tar.gz nextcloud-server-71a0cdceaaad76cd08f48c28d3da40d7fc8d2abf.zip |
Reconnect to DB after timeout for Notify command. Fixes #14479
Signed-off-by: Ari Selseng <ari@selseng.net>
-rw-r--r-- | apps/files_external/lib/Command/Notify.php | 58 |
1 files changed, 48 insertions, 10 deletions
diff --git a/apps/files_external/lib/Command/Notify.php b/apps/files_external/lib/Command/Notify.php index b859a825c80..a0b116f07d9 100644 --- a/apps/files_external/lib/Command/Notify.php +++ b/apps/files_external/lib/Command/Notify.php @@ -2,6 +2,7 @@ /** * @copyright Copyright (c) 2016 Robin Appelman <robin@icewind.nl> * + * @author Ari Selseng <ari@selseng.net> * @author Robin Appelman <robin@icewind.nl> * @author Roeland Jago Douma <roeland@famdouma.nl> * @@ -24,6 +25,7 @@ namespace OCA\Files_External\Command; +use Doctrine\DBAL\Exception\DriverException; use OC\Core\Command\Base; use OCA\Files_External\Lib\InsufficientDataForMeaningfulAnswerException; use OCA\Files_External\Lib\StorageConfig; @@ -52,12 +54,7 @@ class Notify extends Base { parent::__construct(); $this->globalService = $globalService; $this->connection = $connection; - // the query builder doesn't really like subqueries with parameters - $this->updateQuery = $this->connection->prepare( - 'UPDATE *PREFIX*filecache SET size = -1 - WHERE `path` = ? - AND `storage` IN (SELECT storage_id FROM *PREFIX*mounts WHERE mount_id = ?)' - ); + $this->updateQuery = $this->getUpdateQuery($this->connection); } protected function configure() { @@ -143,9 +140,9 @@ class Notify extends Base { $this->logUpdate($change, $output); } if ($change instanceof IRenameChange) { - $this->markParentAsOutdated($mount->getId(), $change->getTargetPath()); + $this->markParentAsOutdated($mount->getId(), $change->getTargetPath(), $output); } - $this->markParentAsOutdated($mount->getId(), $change->getPath()); + $this->markParentAsOutdated($mount->getId(), $change->getPath(), $output); }); } @@ -154,12 +151,20 @@ class Notify extends Base { return new $class($mount->getBackendOptions()); } - private function markParentAsOutdated($mountId, $path) { + private function markParentAsOutdated($mountId, $path, OutputInterface $output) { $parent = ltrim(dirname($path), '/'); if ($parent === '.') { $parent = ''; } - $this->updateQuery->execute([$parent, $mountId]); + + try { + $this->updateQuery->execute([$parent, $mountId]); + } catch (DriverException $th) { + $this->connection = $this->reconnectToDatabase($this->connection, $output); + $output->writeln('<info>Needed to reconnect to the database</info>'); + $this->updateQuery = $this->getUpdateQuery($this->connection); + $this->updateQuery->execute([$parent, $mountId]); + } } private function logUpdate(IChange $change, OutputInterface $output) { @@ -188,6 +193,39 @@ class Notify extends Base { $output->writeln($text); } + /** + * @return \Doctrine\DBAL\Statement + */ + private function getUpdateQuery(IDBConnection $connection) { + // the query builder doesn't really like subqueries with parameters + return $connection->prepare( + 'UPDATE *PREFIX*filecache SET size = -1 + WHERE `path` = ? + AND `storage` IN (SELECT storage_id FROM *PREFIX*mounts WHERE mount_id = ?)' + ); + } + + /** + * @return \OCP\IDBConnection + */ + private function reconnectToDatabase(IDBConnection $connection, OutputInterface $output) { + try { + $connection->close(); + } catch (\Exception $ex) { + $output->writeln("<info>Error while disconnecting from database: {$ex->getMessage()}</info>"); + } + while (!$connection->isConnected()) { + try { + $connection->connect(); + } catch (\Exception $ex) { + $output->writeln("<info>Error while re-connecting to database: {$ex->getMessage()}</info>"); + sleep(60); + } + } + return $connection; + } + + private function selfTest(IStorage $storage, INotifyHandler $notifyHandler, $verbose, OutputInterface $output) { usleep(100 * 1000); //give time for the notify to start $storage->file_put_contents('/.nc_test_file.txt', 'test content'); |