diff --git a/config/config.sample.php b/config/config.sample.php index b663f0bed47..91ac3e379bd 100644 --- a/config/config.sample.php +++ b/config/config.sample.php @@ -3002,4 +3002,12 @@ $CONFIG = [ * Defaults to ``0``. */ 'preview_expiration_days' => 0, + + /** + * Delete job runs older than a certain number of days. + * Less than one day is not allowed. + * + * Defaults to ``60``. + */ + 'background_jobs_expiration_days' => 60, ]; diff --git a/core/BackgroundJobs/CleanupBackgroundJobsJob.php b/core/BackgroundJobs/CleanupBackgroundJobsJob.php index e81242fc6f0..6242941eed1 100644 --- a/core/BackgroundJobs/CleanupBackgroundJobsJob.php +++ b/core/BackgroundJobs/CleanupBackgroundJobsJob.php @@ -19,12 +19,14 @@ use OCP\IConfig; use OCP\IServerInfo; use Override; use Psr\Log\LoggerInterface; +use RuntimeException; class CleanupBackgroundJobsJob extends TimedJob { public function __construct( ITimeFactory $time, private readonly JobRuns $jobRuns, private readonly IServerInfo $serverInfo, + private readonly IConfig $config, private readonly LoggerInterface $logger, ) { parent::__construct($time); @@ -35,8 +37,7 @@ class CleanupBackgroundJobsJob extends TimedJob { #[Override] protected function run($argument): void { $this->reapCrashedJobs(); - - // TODO Clean oldest jobs + $this->cleanOldestRuns(); } private function reapCrashedJobs(): void { @@ -67,4 +68,19 @@ class CleanupBackgroundJobsJob extends TimedJob { } } } + + private function cleanOldestRuns(): void { + $daysToKeep = $this->config->getSystemValueInt('background_jobs_expiration_days', 60); + if ($daysToKeep < 1) { + throw new RuntimeException('Invalid number of days'); + } + $cleanBeforeTimestamp = time() - ($daysToKeep * 24 * 3600); + + $cleanedJobs = $this->jobRuns->deleteBefore($cleanBeforeTimestamp); + if ($cleanedJobs > 0) { + $this->logger->info( + 'Cleanup of old background jobs. Number of jobs removed: ' . $cleanedJobs . 'Reason: older than ' . $daysToKeep . ' days.', + ); + } + } } diff --git a/lib/private/BackgroundJob/JobRuns.php b/lib/private/BackgroundJob/JobRuns.php index 7a19bdf001a..a2612f6655e 100644 --- a/lib/private/BackgroundJob/JobRuns.php +++ b/lib/private/BackgroundJob/JobRuns.php @@ -62,6 +62,18 @@ final readonly class JobRuns implements IJobRuns { return $result === 1; } + public function deleteBefore(int $timestamp): int { + $beforeSnowflake = $this->snowflakeGenerator->minForTimeId($timestamp); + $beforeSnowflake = '91480652934574081'; + $qb = $this->connection->getQueryBuilder(); + $result = $qb + ->delete(self::TABLE) + ->where($qb->expr()->lt('run_id', $qb->createNamedParameter($beforeSnowflake))) + ->executeStatement(); + + return $result; + } + #[Override] public function runningJobs(int $limit = 200): \Generator { $qb = $this->connection->getQueryBuilder();