diff options
-rw-r--r-- | lib/private/BackgroundJob/JobList.php | 18 | ||||
-rw-r--r-- | lib/public/BackgroundJob/IJobList.php | 9 | ||||
-rw-r--r-- | lib/public/BackgroundJob/Job.php | 25 |
3 files changed, 52 insertions, 0 deletions
diff --git a/lib/private/BackgroundJob/JobList.php b/lib/private/BackgroundJob/JobList.php index 67b736b8dd9..6761aa282d1 100644 --- a/lib/private/BackgroundJob/JobList.php +++ b/lib/private/BackgroundJob/JobList.php @@ -35,6 +35,7 @@ use OCP\AppFramework\Utility\ITimeFactory; use OCP\AutoloadNotAllowedException; use OCP\BackgroundJob\IJob; use OCP\BackgroundJob\IJobList; +use OCP\DB\Exception; use OCP\DB\QueryBuilder\IQueryBuilder; use OCP\IConfig; use OCP\IDBConnection; @@ -382,4 +383,21 @@ class JobList implements IJobList { ->where($query->expr()->eq('id', $query->createNamedParameter($job->getId()), IQueryBuilder::PARAM_INT)); $query->executeStatement(); } + + public function hasReservedJob(?string $className): bool { + $query = $this->connection->getQueryBuilder(); + $query->select('*') + ->from('jobs') + ->where($query->expr()->neq('reserved_at', $query->createNamedParameter(0, IQueryBuilder::PARAM_INT))); + + if ($className !== null) { + $query->andWhere($query->expr()->eq('class', $query->createNamedParameter($className))); + } + + try { + return $query->executeQuery()->rowCount() > 0; + } catch (Exception $e) { + return false; + } + } } diff --git a/lib/public/BackgroundJob/IJobList.php b/lib/public/BackgroundJob/IJobList.php index e8d0380e604..71faefb8825 100644 --- a/lib/public/BackgroundJob/IJobList.php +++ b/lib/public/BackgroundJob/IJobList.php @@ -145,4 +145,13 @@ interface IJobList { * @since 23.0.0 */ public function resetBackgroundJob(IJob $job): void; + + /** + * Checks whether a job of the passed class is reserved to run + * + * @param string|null $className + * @return bool + * @since 27.0.0 + */ + public function hasReservedJob(?string $className): bool; } diff --git a/lib/public/BackgroundJob/Job.php b/lib/public/BackgroundJob/Job.php index d60fb5905c9..89ea41381c9 100644 --- a/lib/public/BackgroundJob/Job.php +++ b/lib/public/BackgroundJob/Job.php @@ -43,6 +43,7 @@ abstract class Job implements IJob { protected int $lastRun = 0; protected $argument; protected ITimeFactory $time; + protected bool $allowParallelRuns = true; /** * @since 15.0.0 @@ -72,6 +73,11 @@ abstract class Job implements IJob { $jobList->setLastRun($this); $logger = \OCP\Server::get(LoggerInterface::class); + if (!$this->getAllowParallelRuns() && $jobList->hasReservedJob(get_class($this))) { + $logger->debug('Skipping ' . get_class($this) . ' job with ID ' . $this->getId() . ' because another job with the same class is already running', ['app' => 'cron']); + return; + } + try { $jobStartTime = $this->time->getTime(); $logger->debug('Run ' . get_class($this) . ' job with ID ' . $this->getId(), ['app' => 'cron']); @@ -133,6 +139,25 @@ abstract class Job implements IJob { } /** + * Set this to false to prevent two Jobs from this class from running in parallel + * + * @param bool $allow + * @return void + * @since 27.0.0 + */ + public function setAllowParallelRuns(bool $allow) { + $this->allowParallelRuns = $allow; + } + + /** + * @return bool + * @since 27.0.0 + */ + public function getAllowParallelRuns(): bool { + return $this->allowParallelRuns; + } + + /** * The actual function that is called to run the job * * @param $argument |