diff options
-rw-r--r-- | core/Command/Background/ListCommand.php | 13 | ||||
-rw-r--r-- | lib/private/BackgroundJob/Job.php | 16 | ||||
-rw-r--r-- | lib/private/BackgroundJob/JobList.php | 9 | ||||
-rw-r--r-- | lib/public/BackgroundJob/IJob.php | 13 | ||||
-rw-r--r-- | lib/public/BackgroundJob/IJobList.php | 2 | ||||
-rw-r--r-- | lib/public/BackgroundJob/Job.php | 9 | ||||
-rw-r--r-- | tests/lib/BackgroundJob/DummyJobList.php | 2 |
7 files changed, 54 insertions, 10 deletions
diff --git a/core/Command/Background/ListCommand.php b/core/Command/Background/ListCommand.php index 4116bfa0ff1..aec4ea8439e 100644 --- a/core/Command/Background/ListCommand.php +++ b/core/Command/Background/ListCommand.php @@ -26,6 +26,7 @@ declare(strict_types=1); namespace OC\Core\Command\Background; use OC\Core\Command\Base; +use OCP\BackgroundJob\IJob; use OCP\BackgroundJob\IJobList; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; @@ -61,17 +62,26 @@ class ListCommand extends Base { InputOption::VALUE_OPTIONAL, 'Offset for retrieving jobs', '0' + )->addOption( + 'reserved', + null, + InputOption::VALUE_NONE, + 'Only show reserved jobs' ) ; parent::configure(); } protected function execute(InputInterface $input, OutputInterface $output): int { - $jobs = $this->jobList->getJobsIterator($input->getOption('class'), (int)$input->getOption('limit'), (int)$input->getOption('offset')); + $jobs = $this->jobList->getJobsIterator($input->getOption('class'), (int)$input->getOption('limit'), (int)$input->getOption('offset'), (bool)$input->getOption('reserved')); $this->writeTableInOutputFormat($input, $output, $this->formatJobs($jobs)); return 0; } + /** + * @param iterable<IJob> $jobs + * @return array + */ protected function formatJobs(iterable $jobs): array { $jobsInfo = []; foreach ($jobs as $job) { @@ -79,6 +89,7 @@ class ListCommand extends Base { 'id' => $job->getId(), 'class' => get_class($job), 'last_run' => date(DATE_ATOM, $job->getLastRun()), + 'reserved_at' => $job->getReservedAt() > 0 ? date(DATE_ATOM, $job->getReservedAt()) : 'not reserved', 'argument' => json_encode($job->getArgument()), ]; } diff --git a/lib/private/BackgroundJob/Job.php b/lib/private/BackgroundJob/Job.php index ffcaaf8c36d..ac7ef6bc2ad 100644 --- a/lib/private/BackgroundJob/Job.php +++ b/lib/private/BackgroundJob/Job.php @@ -33,11 +33,9 @@ use OCP\ILogger; * @deprecated internal class, use \OCP\BackgroundJob\Job */ abstract class Job implements IJob { - /** @var int */ - protected $id; - - /** @var int */ - protected $lastRun; + protected int $id; + protected int $lastRun; + protected int $reservedAt; /** @var mixed */ protected $argument; @@ -80,6 +78,10 @@ abstract class Job implements IJob { $this->lastRun = $lastRun; } + public function setReservedAt(int $reservedAt): void { + $this->reservedAt = $reservedAt; + } + public function setArgument($argument) { $this->argument = $argument; } @@ -95,4 +97,8 @@ abstract class Job implements IJob { public function getArgument() { return $this->argument; } + + public function getReservedAt(): int { + return $this->reservedAt; + } } diff --git a/lib/private/BackgroundJob/JobList.php b/lib/private/BackgroundJob/JobList.php index 3cdfee51138..2d365b606ae 100644 --- a/lib/private/BackgroundJob/JobList.php +++ b/lib/private/BackgroundJob/JobList.php @@ -174,7 +174,7 @@ class JobList implements IJobList { * @param IJob|class-string<IJob>|null $job * @return iterable<IJob> Avoid to store these objects as they may share a Singleton instance. You should instead use these IJobs instances while looping on the iterable. */ - public function getJobsIterator($job, ?int $limit, int $offset): iterable { + public function getJobsIterator($job, ?int $limit, int $offset, bool $reservedOnly = false): iterable { $query = $this->connection->getQueryBuilder(); $query->select('*') ->from('jobs') @@ -190,6 +190,10 @@ class JobList implements IJobList { $query->where($query->expr()->eq('class', $query->createNamedParameter($class))); } + if ($reservedOnly) { + $query->where($query->expr()->gt('reserved_at', $query->createNamedParameter($this->timeFactory->getTime() - 12 * 3600, IQueryBuilder::PARAM_INT))); + } + $result = $query->executeQuery(); while ($row = $result->fetch()) { @@ -293,7 +297,7 @@ class JobList implements IJobList { /** * get the job object from a row in the db * - * @param array{class:class-string<IJob>, id:mixed, last_run:mixed, argument:string} $row + * @param array{class:class-string<IJob>, id:mixed, last_run:mixed, argument:string, reserved_at:int} $row * @return ?IJob the next job to run. Beware that this object may be a singleton and may be modified by the next call to buildJob. */ private function buildJob(array $row): ?IJob { @@ -320,6 +324,7 @@ class JobList implements IJobList { $job->setId((int) $row['id']); $job->setLastRun((int) $row['last_run']); $job->setArgument(json_decode($row['argument'], true)); + $job->setReservedAt((int) $row['reserved_at']); return $job; } catch (AutoloadNotAllowedException $e) { // job is from a disabled app, ignore diff --git a/lib/public/BackgroundJob/IJob.php b/lib/public/BackgroundJob/IJob.php index 24d8e7aad4a..e3952d8db0b 100644 --- a/lib/public/BackgroundJob/IJob.php +++ b/lib/public/BackgroundJob/IJob.php @@ -88,6 +88,12 @@ interface IJob { public function setArgument($argument); /** + * @param int $reservedAt + * @since 28.0.0 + */ + public function setReservedAt(int $reservedAt): void; + + /** * Get the id of the background job * This id is determined by the job list when a job is added to the list * @@ -112,4 +118,11 @@ interface IJob { * @since 7.0.0 */ public function getArgument(); + + /** + * Get the timestamp when the job was reserved, or 0 if the job is not currently reserved + * + * @return int + */ + public function getReservedAt(): int; } diff --git a/lib/public/BackgroundJob/IJobList.php b/lib/public/BackgroundJob/IJobList.php index 65e2f5b6250..7b2ad7ef21d 100644 --- a/lib/public/BackgroundJob/IJobList.php +++ b/lib/public/BackgroundJob/IJobList.php @@ -92,7 +92,7 @@ interface IJobList { * @return iterable<IJob> * @since 26.0.0 */ - public function getJobsIterator($job, ?int $limit, int $offset): iterable; + public function getJobsIterator($job, ?int $limit, int $offset, bool $reservedOnly = false): iterable; /** * get the next job in the list diff --git a/lib/public/BackgroundJob/Job.php b/lib/public/BackgroundJob/Job.php index 455fb3d42e7..28ff0a1ec23 100644 --- a/lib/public/BackgroundJob/Job.php +++ b/lib/public/BackgroundJob/Job.php @@ -41,6 +41,7 @@ use Psr\Log\LoggerInterface; abstract class Job implements IJob, IParallelAwareJob { protected int $id = 0; protected int $lastRun = 0; + protected int $reservedAt; protected $argument; protected ITimeFactory $time; protected bool $allowParallelRuns = true; @@ -119,6 +120,10 @@ abstract class Job implements IJob, IParallelAwareJob { $this->argument = $argument; } + public function setReservedAt(int $reservedAt): void { + $this->reservedAt = $reservedAt; + } + /** * @since 15.0.0 */ @@ -140,6 +145,10 @@ abstract class Job implements IJob, IParallelAwareJob { return $this->argument; } + public function getReservedAt(): int { + return $this->reservedAt; + } + /** * Set this to false to prevent two Jobs from this class from running in parallel * diff --git a/tests/lib/BackgroundJob/DummyJobList.php b/tests/lib/BackgroundJob/DummyJobList.php index 42b69cfbe41..1217218eedc 100644 --- a/tests/lib/BackgroundJob/DummyJobList.php +++ b/tests/lib/BackgroundJob/DummyJobList.php @@ -77,7 +77,7 @@ class DummyJobList extends \OC\BackgroundJob\JobList { return $this->jobs; } - public function getJobsIterator($job, ?int $limit, int $offset): array { + public function getJobsIterator($job, ?int $limit, int $offset, bool $reservedOnly = false): array { if ($job instanceof IJob) { $jobClass = get_class($job); } else { |