mirror of
https://github.com/nextcloud/server.git
synced 2026-02-03 20:41:22 -05:00
feat: Port jobs table to snowflakes ids
Signed-off-by: Carl Schwan <carl.schwan@nextcloud.com>
This commit is contained in:
parent
31af870ef0
commit
0e686fc6a9
13 changed files with 147 additions and 178 deletions
|
|
@ -45,7 +45,7 @@ class RefreshWebcalJobTest extends TestCase {
|
|||
#[\PHPUnit\Framework\Attributes\DataProvider('runDataProvider')]
|
||||
public function testRun(int $lastRun, int $time, bool $process): void {
|
||||
$backgroundJob = new RefreshWebcalJob($this->refreshWebcalService, $this->config, $this->logger, $this->timeFactory);
|
||||
$backgroundJob->setId(42);
|
||||
$backgroundJob->setId('42');
|
||||
|
||||
$backgroundJob->setArgument([
|
||||
'principaluri' => 'principals/users/testuser',
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ class Delete extends Base {
|
|||
}
|
||||
|
||||
protected function execute(InputInterface $input, OutputInterface $output): int {
|
||||
$jobId = (int)$input->getArgument('job-id');
|
||||
$jobId = (string)$input->getArgument('job-id');
|
||||
|
||||
$job = $this->jobList->getById($jobId);
|
||||
if ($job === null) {
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ class Job extends Command {
|
|||
}
|
||||
|
||||
protected function execute(InputInterface $input, OutputInterface $output): int {
|
||||
$jobId = (int)$input->getArgument('job-id');
|
||||
$jobId = (string)$input->getArgument('job-id');
|
||||
|
||||
$job = $this->jobList->getById($jobId);
|
||||
if ($job === null) {
|
||||
|
|
@ -87,7 +87,7 @@ class Job extends Command {
|
|||
return 0;
|
||||
}
|
||||
|
||||
protected function printJobInfo(int $jobId, IJob $job, OutputInterface $output): void {
|
||||
protected function printJobInfo(string $jobId, IJob $job, OutputInterface $output): void {
|
||||
$row = $this->jobList->getDetailsById($jobId);
|
||||
|
||||
$lastRun = new \DateTime();
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ abstract class JobBase extends Base {
|
|||
parent::__construct();
|
||||
}
|
||||
|
||||
protected function printJobInfo(int $jobId, IJob $job, OutputInterface $output): void {
|
||||
protected function printJobInfo(string $jobId, IJob $job, OutputInterface $output): void {
|
||||
$row = $this->jobList->getDetailsById($jobId);
|
||||
|
||||
if ($row === null) {
|
||||
|
|
|
|||
33
core/Migrations/Version33000Date20251124110529.php
Normal file
33
core/Migrations/Version33000Date20251124110529.php
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
namespace OC\Core\Migrations;
|
||||
|
||||
use Closure;
|
||||
use OCP\DB\ISchemaWrapper;
|
||||
use OCP\Migration\Attributes\ModifyColumn;
|
||||
use OCP\Migration\IOutput;
|
||||
use OCP\Migration\SimpleMigrationStep;
|
||||
use Override;
|
||||
|
||||
#[ModifyColumn(table: 'jobs', name: 'id', description: 'Remove auto-increment')]
|
||||
class Version33000Date20251124110529 extends SimpleMigrationStep {
|
||||
/**
|
||||
* @param Closure(): ISchemaWrapper $schemaClosure The `\Closure` returns a `ISchemaWrapper`
|
||||
*/
|
||||
#[Override]
|
||||
public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ?ISchemaWrapper {
|
||||
$schema = $schemaClosure();
|
||||
|
||||
if ($schema->hasTable('jobs')) {
|
||||
$schema->dropAutoincrementColumn('jobs', 'id');
|
||||
}
|
||||
|
||||
return $schema;
|
||||
}
|
||||
}
|
||||
|
|
@ -1537,6 +1537,7 @@ return array(
|
|||
'OC\\Core\\Migrations\\Version33000Date20251023110529' => $baseDir . '/core/Migrations/Version33000Date20251023110529.php',
|
||||
'OC\\Core\\Migrations\\Version33000Date20251023120529' => $baseDir . '/core/Migrations/Version33000Date20251023120529.php',
|
||||
'OC\\Core\\Migrations\\Version33000Date20251106131209' => $baseDir . '/core/Migrations/Version33000Date20251106131209.php',
|
||||
'OC\\Core\\Migrations\\Version33000Date20251124110529' => $baseDir . '/core/Migrations/Version33000Date20251124110529.php',
|
||||
'OC\\Core\\Migrations\\Version33000Date20251126152410' => $baseDir . '/core/Migrations/Version33000Date20251126152410.php',
|
||||
'OC\\Core\\Notification\\CoreNotifier' => $baseDir . '/core/Notification/CoreNotifier.php',
|
||||
'OC\\Core\\ResponseDefinitions' => $baseDir . '/core/ResponseDefinitions.php',
|
||||
|
|
|
|||
|
|
@ -1578,6 +1578,7 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2
|
|||
'OC\\Core\\Migrations\\Version33000Date20251023110529' => __DIR__ . '/../../..' . '/core/Migrations/Version33000Date20251023110529.php',
|
||||
'OC\\Core\\Migrations\\Version33000Date20251023120529' => __DIR__ . '/../../..' . '/core/Migrations/Version33000Date20251023120529.php',
|
||||
'OC\\Core\\Migrations\\Version33000Date20251106131209' => __DIR__ . '/../../..' . '/core/Migrations/Version33000Date20251106131209.php',
|
||||
'OC\\Core\\Migrations\\Version33000Date20251124110529' => __DIR__ . '/../../..' . '/core/Migrations/Version33000Date20251124110529.php',
|
||||
'OC\\Core\\Migrations\\Version33000Date20251126152410' => __DIR__ . '/../../..' . '/core/Migrations/Version33000Date20251126152410.php',
|
||||
'OC\\Core\\Notification\\CoreNotifier' => __DIR__ . '/../../..' . '/core/Notification/CoreNotifier.php',
|
||||
'OC\\Core\\ResponseDefinitions' => __DIR__ . '/../../..' . '/core/ResponseDefinitions.php',
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@
|
|||
*/
|
||||
namespace OC\BackgroundJob;
|
||||
|
||||
use OCP\AppFramework\QueryException;
|
||||
use OCP\AppFramework\Utility\ITimeFactory;
|
||||
use OCP\AutoloadNotAllowedException;
|
||||
use OCP\BackgroundJob\IJob;
|
||||
|
|
@ -17,6 +16,9 @@ use OCP\DB\Exception;
|
|||
use OCP\DB\QueryBuilder\IQueryBuilder;
|
||||
use OCP\IConfig;
|
||||
use OCP\IDBConnection;
|
||||
use OCP\Snowflake\IGenerator;
|
||||
use Override;
|
||||
use Psr\Container\ContainerExceptionInterface;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use function get_class;
|
||||
use function json_encode;
|
||||
|
|
@ -24,18 +26,20 @@ use function min;
|
|||
use function strlen;
|
||||
|
||||
class JobList implements IJobList {
|
||||
/** @var array<string, int> */
|
||||
/** @var array<string, string> */
|
||||
protected array $alreadyVisitedParallelBlocked = [];
|
||||
|
||||
public function __construct(
|
||||
protected IDBConnection $connection,
|
||||
protected IConfig $config,
|
||||
protected ITimeFactory $timeFactory,
|
||||
protected LoggerInterface $logger,
|
||||
protected readonly IDBConnection $connection,
|
||||
protected readonly IConfig $config,
|
||||
protected readonly ITimeFactory $timeFactory,
|
||||
protected readonly LoggerInterface $logger,
|
||||
protected readonly IGenerator $generator,
|
||||
) {
|
||||
}
|
||||
|
||||
public function add($job, $argument = null, ?int $firstCheck = null): void {
|
||||
#[Override]
|
||||
public function add(IJob|string $job, mixed $argument = null, ?int $firstCheck = null): void {
|
||||
if ($firstCheck === null) {
|
||||
$firstCheck = $this->timeFactory->getTime();
|
||||
}
|
||||
|
|
@ -51,6 +55,7 @@ class JobList implements IJobList {
|
|||
if (!$this->has($job, $argument)) {
|
||||
$query->insert('jobs')
|
||||
->values([
|
||||
'id' => $query->createNamedParameter($this->generator->nextId(), IQueryBuilder::PARAM_INT),
|
||||
'class' => $query->createNamedParameter($class),
|
||||
'argument' => $query->createNamedParameter($argumentJson),
|
||||
'argument_hash' => $query->createNamedParameter(hash('sha256', $argumentJson)),
|
||||
|
|
@ -68,15 +73,12 @@ class JobList implements IJobList {
|
|||
$query->executeStatement();
|
||||
}
|
||||
|
||||
public function scheduleAfter(string $job, int $runAfter, $argument = null): void {
|
||||
public function scheduleAfter(string $job, int $runAfter, mixed $argument = null): void {
|
||||
$this->add($job, $argument, $runAfter);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param IJob|string $job
|
||||
* @param mixed $argument
|
||||
*/
|
||||
public function remove($job, $argument = null): void {
|
||||
#[Override]
|
||||
public function remove(IJob|string $job, mixed $argument = null): void {
|
||||
$class = ($job instanceof IJob) ? get_class($job) : $job;
|
||||
|
||||
$query = $this->connection->getQueryBuilder();
|
||||
|
|
@ -104,20 +106,16 @@ class JobList implements IJobList {
|
|||
}
|
||||
}
|
||||
|
||||
public function removeById(int $id): void {
|
||||
#[Override]
|
||||
public function removeById(string $id): void {
|
||||
$query = $this->connection->getQueryBuilder();
|
||||
$query->delete('jobs')
|
||||
->where($query->expr()->eq('id', $query->createNamedParameter($id, IQueryBuilder::PARAM_INT)));
|
||||
$query->executeStatement();
|
||||
}
|
||||
|
||||
/**
|
||||
* check if a job is in the list
|
||||
*
|
||||
* @param IJob|class-string<IJob> $job
|
||||
* @param mixed $argument
|
||||
*/
|
||||
public function has($job, $argument): bool {
|
||||
#[Override]
|
||||
public function has(IJob|string $job, mixed $argument): bool {
|
||||
$class = ($job instanceof IJob) ? get_class($job) : $job;
|
||||
$argument = json_encode($argument);
|
||||
|
||||
|
|
@ -135,18 +133,16 @@ class JobList implements IJobList {
|
|||
return (bool)$row;
|
||||
}
|
||||
|
||||
public function getJobs($job, ?int $limit, int $offset): array {
|
||||
#[Override]
|
||||
public function getJobs(IJob|string|null $job, ?int $limit, int $offset): array {
|
||||
$iterable = $this->getJobsIterator($job, $limit, $offset);
|
||||
return (is_array($iterable))
|
||||
? $iterable
|
||||
: iterator_to_array($iterable);
|
||||
}
|
||||
|
||||
/**
|
||||
* @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 {
|
||||
#[Override]
|
||||
public function getJobsIterator(IJob|string|null $job, ?int $limit, int $offset): iterable {
|
||||
$query = $this->connection->getQueryBuilder();
|
||||
$query->select('*')
|
||||
->from('jobs')
|
||||
|
|
@ -169,9 +165,7 @@ class JobList implements IJobList {
|
|||
$result->closeCursor();
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
#[Override]
|
||||
public function getNext(bool $onlyTimeSensitive = false, ?array $jobClasses = null): ?IJob {
|
||||
$query = $this->connection->getQueryBuilder();
|
||||
$query->select('*')
|
||||
|
|
@ -279,10 +273,8 @@ class JobList implements IJobList {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ?IJob The job matching the id. Beware that this object may be a singleton and may be modified by the next call to buildJob.
|
||||
*/
|
||||
public function getById(int $id): ?IJob {
|
||||
#[Override]
|
||||
public function getById(string $id): ?IJob {
|
||||
$row = $this->getDetailsById($id);
|
||||
|
||||
if ($row) {
|
||||
|
|
@ -292,7 +284,8 @@ class JobList implements IJobList {
|
|||
return null;
|
||||
}
|
||||
|
||||
public function getDetailsById(int $id): ?array {
|
||||
#[Override]
|
||||
public function getDetailsById(string $id): ?array {
|
||||
$query = $this->connection->getQueryBuilder();
|
||||
$query->select('*')
|
||||
->from('jobs')
|
||||
|
|
@ -320,7 +313,7 @@ class JobList implements IJobList {
|
|||
// Try to load the job as a service
|
||||
/** @var IJob $job */
|
||||
$job = \OCP\Server::get($row['class']);
|
||||
} catch (QueryException $e) {
|
||||
} catch (ContainerExceptionInterface $e) {
|
||||
if (class_exists($row['class'])) {
|
||||
$class = $row['class'];
|
||||
$job = new $class();
|
||||
|
|
@ -336,7 +329,7 @@ class JobList implements IJobList {
|
|||
// This most likely means an invalid job was enqueued. We can ignore it.
|
||||
return null;
|
||||
}
|
||||
$job->setId((int)$row['id']);
|
||||
$job->setId($row['id']);
|
||||
$job->setLastRun((int)$row['last_run']);
|
||||
$job->setArgument(json_decode($row['argument'], true));
|
||||
return $job;
|
||||
|
|
@ -351,12 +344,10 @@ class JobList implements IJobList {
|
|||
*/
|
||||
public function setLastJob(IJob $job): void {
|
||||
$this->unlockJob($job);
|
||||
$this->config->setAppValue('backgroundjob', 'lastjob', (string)$job->getId());
|
||||
$this->config->setAppValue('backgroundjob', 'lastjob', $job->getId());
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the reservation for a job
|
||||
*/
|
||||
#[Override]
|
||||
public function unlockJob(IJob $job): void {
|
||||
$query = $this->connection->getQueryBuilder();
|
||||
$query->update('jobs')
|
||||
|
|
@ -365,9 +356,7 @@ class JobList implements IJobList {
|
|||
$query->executeStatement();
|
||||
}
|
||||
|
||||
/**
|
||||
* set the lastRun of $job to now
|
||||
*/
|
||||
#[Override]
|
||||
public function setLastRun(IJob $job): void {
|
||||
$query = $this->connection->getQueryBuilder();
|
||||
$query->update('jobs')
|
||||
|
|
@ -382,9 +371,7 @@ class JobList implements IJobList {
|
|||
$query->executeStatement();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $timeTaken
|
||||
*/
|
||||
#[Override]
|
||||
public function setExecutionTime(IJob $job, $timeTaken): void {
|
||||
$query = $this->connection->getQueryBuilder();
|
||||
$query->update('jobs')
|
||||
|
|
@ -394,11 +381,7 @@ class JobList implements IJobList {
|
|||
$query->executeStatement();
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the $job so it executes on the next trigger
|
||||
*
|
||||
* @since 23.0.0
|
||||
*/
|
||||
#[Override]
|
||||
public function resetBackgroundJob(IJob $job): void {
|
||||
$query = $this->connection->getQueryBuilder();
|
||||
$query->update('jobs')
|
||||
|
|
@ -408,6 +391,7 @@ class JobList implements IJobList {
|
|||
$query->executeStatement();
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function hasReservedJob(?string $className = null): bool {
|
||||
$query = $this->connection->getQueryBuilder();
|
||||
$query->select('*')
|
||||
|
|
@ -430,6 +414,7 @@ class JobList implements IJobList {
|
|||
}
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function countByClass(): array {
|
||||
$query = $this->connection->getQueryBuilder();
|
||||
$query->select('class')
|
||||
|
|
@ -444,7 +429,7 @@ class JobList implements IJobList {
|
|||
|
||||
while (($row = $result->fetch()) !== false) {
|
||||
/**
|
||||
* @var array{count:int, class:class-string} $row
|
||||
* @var array{count:int, class:class-string<IJob>} $row
|
||||
*/
|
||||
$jobs[] = $row;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,43 +43,42 @@ interface IJob {
|
|||
|
||||
/**
|
||||
* @since 7.0.0
|
||||
* @since 33.0.0 Parameter $id changed from int to string
|
||||
*/
|
||||
public function setId(int $id);
|
||||
public function setId(string $id): void;
|
||||
|
||||
/**
|
||||
* @since 7.0.0
|
||||
*/
|
||||
public function setLastRun(int $lastRun);
|
||||
public function setLastRun(int $lastRun): void;
|
||||
|
||||
/**
|
||||
* @param mixed $argument
|
||||
* @since 7.0.0
|
||||
*/
|
||||
public function setArgument($argument);
|
||||
public function setArgument(mixed $argument): void;
|
||||
|
||||
/**
|
||||
* Get the id of the background job
|
||||
* This id is determined by the job list when a job is added to the list
|
||||
*
|
||||
* @return int
|
||||
* @since 7.0.0
|
||||
* @since 33.0.0 The return type changed from int to string
|
||||
*/
|
||||
public function getId();
|
||||
public function getId(): string;
|
||||
|
||||
/**
|
||||
* Get the last time this job was run as unix timestamp
|
||||
*
|
||||
* @return int
|
||||
* @since 7.0.0
|
||||
*/
|
||||
public function getLastRun();
|
||||
public function getLastRun(): int;
|
||||
|
||||
/**
|
||||
* Get the argument associated with the background job
|
||||
* This is the argument that will be passed to the background job
|
||||
*
|
||||
* @return mixed
|
||||
* @since 7.0.0
|
||||
*/
|
||||
public function getArgument();
|
||||
public function getArgument(): mixed;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,6 +7,8 @@
|
|||
*/
|
||||
namespace OCP\BackgroundJob;
|
||||
|
||||
use OCP\AppFramework\Attribute\Consumable;
|
||||
|
||||
/**
|
||||
* Interface IJobList
|
||||
*
|
||||
|
|
@ -28,6 +30,7 @@ namespace OCP\BackgroundJob;
|
|||
*
|
||||
* @since 7.0.0
|
||||
*/
|
||||
#[Consumable(since: '7.0.0')]
|
||||
interface IJobList {
|
||||
/**
|
||||
* Add a job to the list
|
||||
|
|
@ -36,7 +39,7 @@ interface IJobList {
|
|||
* @param mixed $argument The argument to be passed to $job->run() when the job is executed
|
||||
* @since 7.0.0
|
||||
*/
|
||||
public function add($job, $argument = null): void;
|
||||
public function add(IJob|string $job, mixed $argument = null): void;
|
||||
|
||||
/**
|
||||
* Add a job to the list but only run it after the given timestamp
|
||||
|
|
@ -49,7 +52,7 @@ interface IJobList {
|
|||
* @param mixed $argument The serializable argument to be passed to $job->run() when the job is executed
|
||||
* @since 28.0.0
|
||||
*/
|
||||
public function scheduleAfter(string $job, int $runAfter, $argument = null): void;
|
||||
public function scheduleAfter(string $job, int $runAfter, mixed $argument = null): void;
|
||||
|
||||
/**
|
||||
* Remove a job from the list
|
||||
|
|
@ -58,15 +61,15 @@ interface IJobList {
|
|||
* @param mixed $argument
|
||||
* @since 7.0.0
|
||||
*/
|
||||
public function remove($job, $argument = null): void;
|
||||
public function remove(IJob|string $job, mixed $argument = null): void;
|
||||
|
||||
/**
|
||||
* Remove a job from the list by id
|
||||
*
|
||||
* @param int $id
|
||||
* @since 30.0.0
|
||||
* @since 33.0.0 Parameter $id changed from int to string
|
||||
*/
|
||||
public function removeById(int $id): void;
|
||||
public function removeById(string $id): void;
|
||||
|
||||
/**
|
||||
* check if a job is in the list
|
||||
|
|
@ -75,7 +78,7 @@ interface IJobList {
|
|||
* @param mixed $argument
|
||||
* @since 7.0.0
|
||||
*/
|
||||
public function has($job, $argument): bool;
|
||||
public function has(IJob|string $job, mixed $argument): bool;
|
||||
|
||||
/**
|
||||
* Get jobs matching the search
|
||||
|
|
@ -85,7 +88,7 @@ interface IJobList {
|
|||
* @since 25.0.0
|
||||
* @deprecated 26.0.0 Use getJobsIterator instead to avoid duplicated job objects
|
||||
*/
|
||||
public function getJobs($job, ?int $limit, int $offset): array;
|
||||
public function getJobs(IJob|string|null $job, ?int $limit, int $offset): array;
|
||||
|
||||
/**
|
||||
* Get jobs matching the search
|
||||
|
|
@ -94,7 +97,7 @@ interface IJobList {
|
|||
* @return iterable<IJob>
|
||||
* @since 26.0.0
|
||||
*/
|
||||
public function getJobsIterator($job, ?int $limit, int $offset): iterable;
|
||||
public function getJobsIterator(IJob|string|null $job, ?int $limit, int $offset): iterable;
|
||||
|
||||
/**
|
||||
* Get the next job in the list
|
||||
|
|
@ -108,13 +111,15 @@ interface IJobList {
|
|||
|
||||
/**
|
||||
* @since 7.0.0
|
||||
* @since 33.0.0 Parameter $id changed from int to string
|
||||
*/
|
||||
public function getById(int $id): ?IJob;
|
||||
public function getById(string $id): ?IJob;
|
||||
|
||||
/**
|
||||
* @since 23.0.0
|
||||
* @since 33.0.0 Parameter $id changed from int to string
|
||||
*/
|
||||
public function getDetailsById(int $id): ?array;
|
||||
public function getDetailsById(string $id): ?array;
|
||||
|
||||
/**
|
||||
* set the job that was last ran to the current time
|
||||
|
|
@ -155,7 +160,7 @@ interface IJobList {
|
|||
* Checks whether a job of the passed class was reserved to run
|
||||
* in the last 6h
|
||||
*
|
||||
* @param string|null $className
|
||||
* @param class-string<IJob>|null $className
|
||||
* @return bool
|
||||
* @since 27.0.0
|
||||
*/
|
||||
|
|
@ -164,7 +169,7 @@ interface IJobList {
|
|||
/**
|
||||
* Returns a count of jobs per Job class
|
||||
*
|
||||
* @return list<array{class:class-string, count:int}>
|
||||
* @return list<array{class:class-string<IJob>, count:int}>
|
||||
* @since 30.0.0
|
||||
*/
|
||||
public function countByClass(): array;
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ declare(strict_types=1);
|
|||
namespace OCP\BackgroundJob;
|
||||
|
||||
use OCP\AppFramework\Utility\ITimeFactory;
|
||||
use Override;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
/**
|
||||
|
|
@ -21,7 +22,7 @@ use Psr\Log\LoggerInterface;
|
|||
* @since 33.0.0 removed deprecated `execute()` method
|
||||
*/
|
||||
abstract class Job implements IJob, IParallelAwareJob {
|
||||
protected int $id = 0;
|
||||
protected string $id = '0';
|
||||
protected int $lastRun = 0;
|
||||
protected mixed $argument = null;
|
||||
protected bool $allowParallelRuns = true;
|
||||
|
|
@ -34,10 +35,7 @@ abstract class Job implements IJob, IParallelAwareJob {
|
|||
) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
* @since 25.0.0
|
||||
*/
|
||||
#[Override]
|
||||
public function start(IJobList $jobList): void {
|
||||
$jobList->setLastRun($this);
|
||||
$logger = \OCP\Server::get(LoggerInterface::class);
|
||||
|
|
@ -61,74 +59,45 @@ abstract class Job implements IJob, IParallelAwareJob {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 15.0.0
|
||||
*/
|
||||
final public function setId(int $id) {
|
||||
#[Override]
|
||||
final public function setId(string $id): void {
|
||||
$this->id = $id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 15.0.0
|
||||
*/
|
||||
final public function setLastRun(int $lastRun) {
|
||||
#[Override]
|
||||
final public function setLastRun(int $lastRun): void {
|
||||
$this->lastRun = $lastRun;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 15.0.0
|
||||
*/
|
||||
public function setArgument($argument) {
|
||||
#[Override]
|
||||
public function setArgument(mixed $argument): void {
|
||||
$this->argument = $argument;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 15.0.0
|
||||
*/
|
||||
final public function getId(): int {
|
||||
#[Override]
|
||||
final public function getId(): string {
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 15.0.0
|
||||
*/
|
||||
#[Override]
|
||||
final public function getLastRun(): int {
|
||||
return $this->lastRun;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 15.0.0
|
||||
*/
|
||||
public function getArgument() {
|
||||
#[Override]
|
||||
public function getArgument(): mixed {
|
||||
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
|
||||
*/
|
||||
#[Override]
|
||||
public function setAllowParallelRuns(bool $allow): void {
|
||||
$this->allowParallelRuns = $allow;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
* @since 27.0.0
|
||||
*/
|
||||
#[Override]
|
||||
public function getAllowParallelRuns(): bool {
|
||||
return $this->allowParallelRuns;
|
||||
}
|
||||
|
||||
/**
|
||||
* The actual function that is called to run the job
|
||||
*
|
||||
* @param $argument
|
||||
* @return void
|
||||
*
|
||||
* @since 15.0.0
|
||||
*/
|
||||
abstract protected function run($argument);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ use OC\BackgroundJob\JobList;
|
|||
use OCP\BackgroundJob\IJob;
|
||||
use OCP\BackgroundJob\Job;
|
||||
use OCP\Server;
|
||||
use OCP\Snowflake\IGenerator;
|
||||
|
||||
/**
|
||||
* Class DummyJobList
|
||||
|
|
@ -31,7 +32,6 @@ class DummyJobList extends JobList {
|
|||
private array $reserved = [];
|
||||
|
||||
private int $last = 0;
|
||||
private int $lastId = 0;
|
||||
|
||||
public function __construct() {
|
||||
}
|
||||
|
|
@ -46,8 +46,7 @@ class DummyJobList extends JobList {
|
|||
$job = Server::get($job);
|
||||
}
|
||||
$job->setArgument($argument);
|
||||
$job->setId($this->lastId);
|
||||
$this->lastId++;
|
||||
$job->setId(Server::get(IGenerator::class)->nextId());
|
||||
if (!$this->has($job, null)) {
|
||||
$this->jobs[] = $job;
|
||||
}
|
||||
|
|
@ -70,7 +69,7 @@ class DummyJobList extends JobList {
|
|||
}
|
||||
}
|
||||
|
||||
public function removeById(int $id): void {
|
||||
public function removeById(string $id): void {
|
||||
foreach ($this->jobs as $index => $listJob) {
|
||||
if ($listJob->getId() === $id) {
|
||||
unset($this->jobs[$index]);
|
||||
|
|
@ -148,7 +147,7 @@ class DummyJobList extends JobList {
|
|||
}
|
||||
}
|
||||
|
||||
public function getById(int $id): ?IJob {
|
||||
public function getById(string $id): ?IJob {
|
||||
foreach ($this->jobs as $job) {
|
||||
if ($job->getId() === $id) {
|
||||
return $job;
|
||||
|
|
@ -157,7 +156,7 @@ class DummyJobList extends JobList {
|
|||
return null;
|
||||
}
|
||||
|
||||
public function getDetailsById(int $id): ?array {
|
||||
public function getDetailsById(string $id): ?array {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -12,11 +12,13 @@ namespace Test\BackgroundJob;
|
|||
|
||||
use OC\BackgroundJob\JobList;
|
||||
use OCP\AppFramework\Utility\ITimeFactory;
|
||||
use OCP\BackgroundJob\IJob;
|
||||
use OCP\DB\QueryBuilder\IQueryBuilder;
|
||||
use OCP\IConfig;
|
||||
use OCP\IDBConnection;
|
||||
use OCP\Server;
|
||||
use OCP\Snowflake\IGenerator;
|
||||
use PHPUnit\Framework\Attributes\DataProvider;
|
||||
use PHPUnit\Framework\MockObject\MockObject;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Test\TestCase;
|
||||
|
||||
|
|
@ -27,18 +29,10 @@ use Test\TestCase;
|
|||
*/
|
||||
#[\PHPUnit\Framework\Attributes\Group('DB')]
|
||||
class JobListTest extends TestCase {
|
||||
/** @var \OC\BackgroundJob\JobList */
|
||||
protected $instance;
|
||||
|
||||
/** @var IDBConnection */
|
||||
protected $connection;
|
||||
|
||||
/** @var IConfig|\PHPUnit\Framework\MockObject\MockObject */
|
||||
protected $config;
|
||||
|
||||
/** @var ITimeFactory|\PHPUnit\Framework\MockObject\MockObject */
|
||||
protected $timeFactory;
|
||||
private bool $ran = false;
|
||||
protected JobList $instance;
|
||||
protected IDBConnection $connection;
|
||||
protected IConfig&MockObject $config;
|
||||
protected ITimeFactory&MockObject $timeFactory;
|
||||
|
||||
protected function setUp(): void {
|
||||
parent::setUp();
|
||||
|
|
@ -52,16 +46,17 @@ class JobListTest extends TestCase {
|
|||
$this->config,
|
||||
$this->timeFactory,
|
||||
Server::get(LoggerInterface::class),
|
||||
Server::get(IGenerator::class),
|
||||
);
|
||||
}
|
||||
|
||||
protected function clearJobsList() {
|
||||
protected function clearJobsList(): void {
|
||||
$query = $this->connection->getQueryBuilder();
|
||||
$query->delete('jobs');
|
||||
$query->executeStatement();
|
||||
}
|
||||
|
||||
protected function getAllSorted() {
|
||||
protected function getAllSorted(): array {
|
||||
$iterator = $this->instance->getJobsIterator(null, null, 0);
|
||||
$jobs = [];
|
||||
|
||||
|
|
@ -69,10 +64,6 @@ class JobListTest extends TestCase {
|
|||
$jobs[] = clone $job;
|
||||
}
|
||||
|
||||
usort($jobs, function (IJob $job1, IJob $job2) {
|
||||
return $job1->getId() - $job2->getId();
|
||||
});
|
||||
|
||||
return $jobs;
|
||||
}
|
||||
|
||||
|
|
@ -89,11 +80,8 @@ class JobListTest extends TestCase {
|
|||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $argument
|
||||
*/
|
||||
#[\PHPUnit\Framework\Attributes\DataProvider('argumentProvider')]
|
||||
public function testAddRemove($argument): void {
|
||||
#[DataProvider('argumentProvider')]
|
||||
public function testAddRemove(mixed $argument): void {
|
||||
$existingJobs = $this->getAllSorted();
|
||||
$job = new TestJob();
|
||||
$this->instance->add($job, $argument);
|
||||
|
|
@ -111,11 +99,8 @@ class JobListTest extends TestCase {
|
|||
$this->assertEquals($existingJobs, $jobs);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $argument
|
||||
*/
|
||||
#[\PHPUnit\Framework\Attributes\DataProvider('argumentProvider')]
|
||||
public function testRemoveDifferentArgument($argument): void {
|
||||
#[DataProvider('argumentProvider')]
|
||||
public function testRemoveDifferentArgument(mixed $argument): void {
|
||||
$existingJobs = $this->getAllSorted();
|
||||
$job = new TestJob();
|
||||
$this->instance->add($job, $argument);
|
||||
|
|
@ -132,11 +117,8 @@ class JobListTest extends TestCase {
|
|||
$this->assertEquals($existingJobs, $jobs);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $argument
|
||||
*/
|
||||
#[\PHPUnit\Framework\Attributes\DataProvider('argumentProvider')]
|
||||
public function testHas($argument): void {
|
||||
#[DataProvider('argumentProvider')]
|
||||
public function testHas(mixed $argument): void {
|
||||
$job = new TestJob();
|
||||
$this->assertFalse($this->instance->has($job, $argument));
|
||||
$this->instance->add($job, $argument);
|
||||
|
|
@ -148,11 +130,8 @@ class JobListTest extends TestCase {
|
|||
$this->assertFalse($this->instance->has($job, $argument));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $argument
|
||||
*/
|
||||
#[\PHPUnit\Framework\Attributes\DataProvider('argumentProvider')]
|
||||
public function testHasDifferentArgument($argument): void {
|
||||
#[DataProvider('argumentProvider')]
|
||||
public function testHasDifferentArgument(mixed $argument): void {
|
||||
$job = new TestJob();
|
||||
$this->instance->add($job, $argument);
|
||||
|
||||
|
|
@ -163,14 +142,16 @@ class JobListTest extends TestCase {
|
|||
$argument,
|
||||
int $reservedTime = 0,
|
||||
int $lastChecked = 0,
|
||||
int $lastRun = 0): int {
|
||||
int $lastRun = 0): string {
|
||||
if ($lastChecked === 0) {
|
||||
$lastChecked = time();
|
||||
}
|
||||
$id = Server::get(IGenerator::class)->nextId();
|
||||
|
||||
$query = $this->connection->getQueryBuilder();
|
||||
$query->insert('jobs')
|
||||
->values([
|
||||
'id' => $query->createNamedParameter($id, IQueryBuilder::PARAM_INT),
|
||||
'class' => $query->createNamedParameter($class),
|
||||
'argument' => $query->createNamedParameter($argument),
|
||||
'last_run' => $query->createNamedParameter($lastRun, IQueryBuilder::PARAM_INT),
|
||||
|
|
@ -178,7 +159,7 @@ class JobListTest extends TestCase {
|
|||
'reserved_at' => $query->createNamedParameter($reservedTime, IQueryBuilder::PARAM_INT),
|
||||
]);
|
||||
$query->executeStatement();
|
||||
return $query->getLastInsertId();
|
||||
return $id;
|
||||
}
|
||||
|
||||
public function testGetNext(): void {
|
||||
|
|
@ -243,7 +224,7 @@ class JobListTest extends TestCase {
|
|||
/**
|
||||
* @param $argument
|
||||
*/
|
||||
#[\PHPUnit\Framework\Attributes\DataProvider('argumentProvider')]
|
||||
#[DataProvider('argumentProvider')]
|
||||
public function testGetById($argument): void {
|
||||
$job = new TestJob();
|
||||
$this->instance->add($job, $argument);
|
||||
|
|
@ -334,8 +315,4 @@ class JobListTest extends TestCase {
|
|||
$job = $this->instance->getNext();
|
||||
$this->assertNull($job); // Job doesn't allow parallel runs
|
||||
}
|
||||
|
||||
public function markRun() {
|
||||
$this->ran = true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue