Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nextcloud/server.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAri Selseng <ari@selseng.net>2019-03-03 03:36:27 +0300
committerRobin Appelman <robin@icewind.nl>2019-04-08 18:23:32 +0300
commit576711ac1931c6e845f66d8c1dadcea178a13813 (patch)
tree79f59b9c4c156d34978fe7e1bc32da228648d4c7
parent3acee4f1b4feed08fee973607a6eb49daecc48fb (diff)
Reconnect to DB after timeout for Notify command. Fixes #14479notify-db-reconnect015
Signed-off-by: Ari Selseng <ari@selseng.net>
-rw-r--r--apps/files_external/lib/Command/Notify.php58
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');