From 2bcc4662e709fd54395d07c25f36ad8063321adc Mon Sep 17 00:00:00 2001 From: Christoph Wurst Date: Wed, 12 Feb 2025 09:54:07 +0100 Subject: [PATCH] perf(cron): Delay (re)checking timed jobs Signed-off-by: Christoph Wurst --- lib/private/BackgroundJob/JobList.php | 21 +++++++++++++++++++++ lib/public/BackgroundJob/TimedJob.php | 9 +++++++++ 2 files changed, 30 insertions(+) diff --git a/lib/private/BackgroundJob/JobList.php b/lib/private/BackgroundJob/JobList.php index 5552142171132..f58d2e8db8220 100644 --- a/lib/private/BackgroundJob/JobList.php +++ b/lib/private/BackgroundJob/JobList.php @@ -20,6 +20,7 @@ use Psr\Log\LoggerInterface; use function get_class; use function json_encode; +use function min; use function strlen; class JobList implements IJobList { @@ -209,6 +210,26 @@ public function getNext(bool $onlyTimeSensitive = false, ?array $jobClasses = nu return $this->getNext($onlyTimeSensitive); } + if ($job instanceof \OCP\BackgroundJob\TimedJob) { + $now = $this->timeFactory->getTime(); + $nextPossibleRun = $job->getLastRun() + $job->getInterval(); + if ($now < $nextPossibleRun) { + // This job is not ready for execution yet. Set timestamps to the future to avoid + // re-checking with every cron run. + // To avoid bugs that lead to jobs never executing again, the future timestamp is + // capped at two days. + $nextCheck = min($nextPossibleRun, $now + 48 * 3600); + $updateTimedJob = $this->connection->getQueryBuilder(); + $updateTimedJob->update('jobs') + ->set('last_checked', $updateTimedJob->createNamedParameter($nextCheck, IQueryBuilder::PARAM_INT)) + ->where($updateTimedJob->expr()->eq('id', $updateTimedJob->createParameter('jobid'))); + $updateTimedJob->setParameter('jobid', $row['id']); + $updateTimedJob->executeStatement(); + + return $this->getNext($onlyTimeSensitive, $jobClasses); + } + } + $update = $this->connection->getQueryBuilder(); $update->update('jobs') ->set('reserved_at', $update->createNamedParameter($this->timeFactory->getTime())) diff --git a/lib/public/BackgroundJob/TimedJob.php b/lib/public/BackgroundJob/TimedJob.php index 85ca34665b41c..296bd9e4e3222 100644 --- a/lib/public/BackgroundJob/TimedJob.php +++ b/lib/public/BackgroundJob/TimedJob.php @@ -32,6 +32,15 @@ public function setInterval(int $seconds) { $this->interval = $seconds; } + /** + * Get the interval [seconds] for the job + * + * @since 32.0.0 + */ + public function getInterval(): int { + return $this->interval; + } + /** * Whether the background job is time sensitive and needs to run soon after * the scheduled interval, of if it is okay to be delayed until a later time.