mirror of
https://github.com/nextcloud/server.git
synced 2026-06-08 16:26:59 -04:00
feat(BackgroundJobs): Allow preventing parallel runs for a job class
Signed-off-by: Marcel Klehr <mklehr@gmx.net>
This commit is contained in:
parent
f4f6431d4d
commit
c01c516323
3 changed files with 52 additions and 0 deletions
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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']);
|
||||
|
|
@ -132,6 +138,25 @@ abstract class Job implements IJob {
|
|||
return $this->argument;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
*
|
||||
|
|
|
|||
Loading…
Reference in a new issue