feat(jobs): clean old job runs

Signed-off-by: Benjamin Gaussorgues <benjamin.gaussorgues@nextcloud.com>
This commit is contained in:
Benjamin Gaussorgues 2026-06-04 20:30:47 +02:00
parent 28d32d8fff
commit dc5499af46
No known key found for this signature in database
3 changed files with 38 additions and 2 deletions

View file

@ -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,
];

View file

@ -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.',
);
}
}
}

View file

@ -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();