From a1a29d14c8cdeb3d5a5e541ec73ff3f42f11ee03 Mon Sep 17 00:00:00 2001 From: Morris Jobke Date: Tue, 26 Jun 2018 16:24:08 +0200 Subject: [PATCH 1/4] Unlock failed cron jobs and set a high "last_checked" value to avoid continous re-check * fixes issue where cronjobs of a not-loaded app are marked as "still running" because there is a "reserved_at" value stored * fixed #9992 Signed-off-by: Morris Jobke --- lib/private/BackgroundJob/JobList.php | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/lib/private/BackgroundJob/JobList.php b/lib/private/BackgroundJob/JobList.php index a926194e9dff5..856354f1590b7 100644 --- a/lib/private/BackgroundJob/JobList.php +++ b/lib/private/BackgroundJob/JobList.php @@ -186,6 +186,7 @@ public function getNext() { $query->select('*') ->from('jobs') ->where($query->expr()->lte('reserved_at', $query->createNamedParameter($this->timeFactory->getTime() - $this->jobTimeOut, IQueryBuilder::PARAM_INT))) + ->andWhere($query->expr()->lte('last_checked', $query->createNamedParameter($this->timeFactory->getTime(), IQueryBuilder::PARAM_INT))) ->orderBy('last_checked', 'ASC') ->setMaxResults(1); @@ -214,6 +215,14 @@ public function getNext() { $job = $this->buildJob($row); if ($job === null) { + // set the last_checked to 12h in the future to not check failing jobs all over again + $reset = $this->connection->getQueryBuilder(); + $reset->update('jobs') + ->set('reserved_at', $reset->expr()->literal(0, IQueryBuilder::PARAM_INT)) + ->set('last_checked', $reset->createNamedParameter($this->timeFactory->getTime() + 12 * 3600, IQueryBuilder::PARAM_INT)) + ->where($reset->expr()->eq('id', $reset->createNamedParameter($row['id'], IQueryBuilder::PARAM_INT))); + $reset->execute(); + // Background job from disabled app, try again. return $this->getNext(); } From 8b1084adfe6de26d8b0c28df18756640ed0d4093 Mon Sep 17 00:00:00 2001 From: Morris Jobke Date: Tue, 26 Jun 2018 16:35:38 +0200 Subject: [PATCH 2/4] Only wait for cron if fix for endless wait is included * see https://github.com/nextcloud/server/issues/9992 Signed-off-by: Morris Jobke --- lib/private/Updater.php | 8 ++++++-- version.php | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/lib/private/Updater.php b/lib/private/Updater.php index 02b3138f30fe0..4098d1b767d72 100644 --- a/lib/private/Updater.php +++ b/lib/private/Updater.php @@ -111,10 +111,14 @@ public function upgrade() { $this->emit('\OC\Updater', 'maintenanceEnabled'); } - $this->waitForCronToFinish(); - $installedVersion = $this->config->getSystemValue('version', '0.0.0'); $currentVersion = implode('.', \OCP\Util::getVersion()); + + // see https://github.com/nextcloud/server/issues/9992 for potential problem + if (version_compare($installedVersion, '14.0.0.9', '>=')) { + $this->waitForCronToFinish(); + } + $this->log->debug('starting upgrade from ' . $installedVersion . ' to ' . $currentVersion, array('app' => 'core')); $success = true; diff --git a/version.php b/version.php index 13501453cc640..93a2001444e1d 100644 --- a/version.php +++ b/version.php @@ -29,7 +29,7 @@ // between betas, final and RCs. This is _not_ the public version number. Reset minor/patchlevel // when updating major/minor version number. -$OC_Version = array(14, 0, 0, 8); +$OC_Version = array(14, 0, 0, 9); // The human readable string $OC_VersionString = '14.0.0 alpha'; From 8a64433ec91aadad417e595ac63743d1b491b018 Mon Sep 17 00:00:00 2001 From: Morris Jobke Date: Thu, 5 Jul 2018 12:27:36 +0200 Subject: [PATCH 3/4] Add repair job for pending cron jobs Signed-off-by: Morris Jobke --- lib/composer/composer/autoload_classmap.php | 1 + lib/composer/composer/autoload_static.php | 1 + lib/private/Repair.php | 2 + .../Repair/NC14/RepairPendingCronJobs.php | 74 +++++++++++++++++++ 4 files changed, 78 insertions(+) create mode 100644 lib/private/Repair/NC14/RepairPendingCronJobs.php diff --git a/lib/composer/composer/autoload_classmap.php b/lib/composer/composer/autoload_classmap.php index d2648c2db637c..faf17a109b24d 100644 --- a/lib/composer/composer/autoload_classmap.php +++ b/lib/composer/composer/autoload_classmap.php @@ -893,6 +893,7 @@ 'OC\\Repair\\NC13\\AddLogRotateJob' => $baseDir . '/lib/private/Repair/NC13/AddLogRotateJob.php', 'OC\\Repair\\NC13\\RepairInvalidPaths' => $baseDir . '/lib/private/Repair/NC13/RepairInvalidPaths.php', 'OC\\Repair\\NC14\\AddPreviewBackgroundCleanupJob' => $baseDir . '/lib/private/Repair/NC14/AddPreviewBackgroundCleanupJob.php', + 'OC\\Repair\\NC14\\RepairPendingCronJobs' => $baseDir . '/lib/private/Repair/NC14/RepairPendingCronJobs.php', 'OC\\Repair\\OldGroupMembershipShares' => $baseDir . '/lib/private/Repair/OldGroupMembershipShares.php', 'OC\\Repair\\Owncloud\\DropAccountTermsTable' => $baseDir . '/lib/private/Repair/Owncloud/DropAccountTermsTable.php', 'OC\\Repair\\Owncloud\\SaveAccountsTableData' => $baseDir . '/lib/private/Repair/Owncloud/SaveAccountsTableData.php', diff --git a/lib/composer/composer/autoload_static.php b/lib/composer/composer/autoload_static.php index 4a2580fe757f9..a8d748137e881 100644 --- a/lib/composer/composer/autoload_static.php +++ b/lib/composer/composer/autoload_static.php @@ -923,6 +923,7 @@ class ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c 'OC\\Repair\\NC13\\AddLogRotateJob' => __DIR__ . '/../../..' . '/lib/private/Repair/NC13/AddLogRotateJob.php', 'OC\\Repair\\NC13\\RepairInvalidPaths' => __DIR__ . '/../../..' . '/lib/private/Repair/NC13/RepairInvalidPaths.php', 'OC\\Repair\\NC14\\AddPreviewBackgroundCleanupJob' => __DIR__ . '/../../..' . '/lib/private/Repair/NC14/AddPreviewBackgroundCleanupJob.php', + 'OC\\Repair\\NC14\\RepairPendingCronJobs' => __DIR__ . '/../../..' . '/lib/private/Repair/NC14/RepairPendingCronJobs.php', 'OC\\Repair\\OldGroupMembershipShares' => __DIR__ . '/../../..' . '/lib/private/Repair/OldGroupMembershipShares.php', 'OC\\Repair\\Owncloud\\DropAccountTermsTable' => __DIR__ . '/../../..' . '/lib/private/Repair/Owncloud/DropAccountTermsTable.php', 'OC\\Repair\\Owncloud\\SaveAccountsTableData' => __DIR__ . '/../../..' . '/lib/private/Repair/Owncloud/SaveAccountsTableData.php', diff --git a/lib/private/Repair.php b/lib/private/Repair.php index 78a60392219c0..ad9662ca1d7e0 100644 --- a/lib/private/Repair.php +++ b/lib/private/Repair.php @@ -38,6 +38,7 @@ use OC\Repair\NC11\FixMountStorages; use OC\Repair\NC13\AddLogRotateJob; use OC\Repair\NC14\AddPreviewBackgroundCleanupJob; +use OC\Repair\NC14\RepairPendingCronJobs; use OC\Repair\OldGroupMembershipShares; use OC\Repair\Owncloud\DropAccountTermsTable; use OC\Repair\Owncloud\SaveAccountsTableData; @@ -137,6 +138,7 @@ public static function getRepairSteps() { new ClearFrontendCaches(\OC::$server->getMemCacheFactory(), \OC::$server->query(SCSSCacher::class), \OC::$server->query(JSCombiner::class)), new AddPreviewBackgroundCleanupJob(\OC::$server->getJobList()), new AddCleanupUpdaterBackupsJob(\OC::$server->getJobList()), + new RepairPendingCronJobs(\OC::$server->getDatabaseConnection(), \OC::$server->getConfig()), ]; } diff --git a/lib/private/Repair/NC14/RepairPendingCronJobs.php b/lib/private/Repair/NC14/RepairPendingCronJobs.php new file mode 100644 index 0000000000000..c685cefdf861d --- /dev/null +++ b/lib/private/Repair/NC14/RepairPendingCronJobs.php @@ -0,0 +1,74 @@ + + * + * @author Morris Jobke + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +namespace OC\Repair\NC14; + +use OCP\DB\QueryBuilder\IQueryBuilder; +use OCP\IConfig; +use OCP\IDBConnection; +use OCP\Migration\IOutput; +use OCP\Migration\IRepairStep; + +class RepairPendingCronJobs implements IRepairStep { + const MAX_ROWS = 1000; + + /** @var IDBConnection */ + private $connection; + /** @var IConfig */ + private $config; + + public function __construct(IDBConnection $connection, IConfig $config) { + $this->connection = $connection; + $this->config = $config; + } + + + public function getName() { + return 'Repair pending cron jobs'; + } + + private function shouldRun() { + $versionFromBeforeUpdate = $this->config->getSystemValue('version', '0.0.0'); + + return version_compare($versionFromBeforeUpdate, '14.0.0.9', '<'); + } + + private function repair() { + $reset = $this->connection->getQueryBuilder(); + $reset->update('jobs') + ->set('reserved_at', $reset->expr()->literal(0, IQueryBuilder::PARAM_INT)) + ->where($reset->expr()->neq('reserved_at', $reset->expr()->literal(0, IQueryBuilder::PARAM_INT))); + + return $reset->execute(); + } + + public function run(IOutput $output) { + if ($this->shouldRun()) { + $count = $this->repair(); + + $output->info('Repaired ' . $count . ' pending cron job(s).'); + } else { + $output->info('No need to repair pending cron jobs.'); + } + } +} From 79801ad263f2862106204263a4fbd72cd343df82 Mon Sep 17 00:00:00 2001 From: Morris Jobke Date: Mon, 9 Jul 2018 14:55:47 +0200 Subject: [PATCH 4/4] Suppress potential SQL injection warning as they are false positives Signed-off-by: Morris Jobke --- lib/private/BackgroundJob/JobList.php | 1 + lib/private/Repair/NC14/RepairPendingCronJobs.php | 3 +++ 2 files changed, 4 insertions(+) diff --git a/lib/private/BackgroundJob/JobList.php b/lib/private/BackgroundJob/JobList.php index 856354f1590b7..fab608cf16496 100644 --- a/lib/private/BackgroundJob/JobList.php +++ b/lib/private/BackgroundJob/JobList.php @@ -180,6 +180,7 @@ public function getAll() { * get the next job in the list * * @return IJob|null + * @suppress SqlInjectionChecker */ public function getNext() { $query = $this->connection->getQueryBuilder(); diff --git a/lib/private/Repair/NC14/RepairPendingCronJobs.php b/lib/private/Repair/NC14/RepairPendingCronJobs.php index c685cefdf861d..a8ca2c75e89e1 100644 --- a/lib/private/Repair/NC14/RepairPendingCronJobs.php +++ b/lib/private/Repair/NC14/RepairPendingCronJobs.php @@ -53,6 +53,9 @@ private function shouldRun() { return version_compare($versionFromBeforeUpdate, '14.0.0.9', '<'); } + /** + * @suppress SqlInjectionChecker + */ private function repair() { $reset = $this->connection->getQueryBuilder(); $reset->update('jobs')