From 18e9631810ad1d3d72c2b4bbee330169808108ad Mon Sep 17 00:00:00 2001 From: Morris Jobke Date: Mon, 18 Jun 2018 17:23:54 +0200 Subject: Wait for cron to finish before running upgrade command * fixes #9562 Signed-off-by: Morris Jobke --- lib/private/BackgroundJob/JobList.php | 40 ++++++++++++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) (limited to 'lib/private/BackgroundJob') diff --git a/lib/private/BackgroundJob/JobList.php b/lib/private/BackgroundJob/JobList.php index 1399683dc9b..a926194e9df 100644 --- a/lib/private/BackgroundJob/JobList.php +++ b/lib/private/BackgroundJob/JobList.php @@ -48,6 +48,9 @@ class JobList implements IJobList { /**@var ITimeFactory */ protected $timeFactory; + /** @var int - 12 hours * 3600 seconds*/ + private $jobTimeOut = 43200; + /** * @param IDBConnection $connection * @param IConfig $config @@ -182,7 +185,7 @@ class JobList implements IJobList { $query = $this->connection->getQueryBuilder(); $query->select('*') ->from('jobs') - ->where($query->expr()->lte('reserved_at', $query->createNamedParameter($this->timeFactory->getTime() - 12 * 3600, IQueryBuilder::PARAM_INT))) + ->where($query->expr()->lte('reserved_at', $query->createNamedParameter($this->timeFactory->getTime() - $this->jobTimeOut, IQueryBuilder::PARAM_INT))) ->orderBy('last_checked', 'ASC') ->setMaxResults(1); @@ -333,4 +336,39 @@ class JobList implements IJobList { ->where($query->expr()->eq('id', $query->createNamedParameter($job->getId(), IQueryBuilder::PARAM_INT))); $query->execute(); } + + /** + * checks if a job is still running (reserved_at time is smaller than 12 hours ago) + * + * Background information: + * + * The 12 hours is the same timeout that is also used to re-schedule an non-terminated + * job (see getNext()). The idea here is to give a job enough time to run very + * long but still be able to recognize that it maybe crashed and re-schedule it + * after the timeout. It's more likely to be crashed at that time than it ran + * that long. + * + * In theory it could lead to an nearly endless loop (as in - at most 12 hours). + * The cron command will not start new jobs when maintenance mode is active and + * this method is only executed in maintenance mode (see where it is called in + * the upgrader class. So this means in the worst case we wait 12 hours when a + * job has crashed. On the other hand: then the instance should be fixed anyways. + * + * @return bool + */ + public function isAnyJobRunning(): bool { + $query = $this->connection->getQueryBuilder(); + $query->select('*') + ->from('jobs') + ->where($query->expr()->gt('reserved_at', $query->createNamedParameter($this->timeFactory->getTime() - $this->jobTimeOut, IQueryBuilder::PARAM_INT))) + ->setMaxResults(1); + $result = $query->execute(); + $row = $result->fetch(); + $result->closeCursor(); + + if ($row) { + return true; + } + return false; + } } -- cgit v1.2.3