From 9e25cf3fe1f604aa44552714fba145f856c7b105 Mon Sep 17 00:00:00 2001 From: Kostiantyn Miakshyn Date: Thu, 3 Sep 2026 14:53:04 +0200 Subject: [PATCH] perf(cleanup): Optimize cleanup job Signed-off-by: Kostiantyn Miakshyn --- lib/Cron/Cleanup.php | 19 ++++++++++++++++++- lib/Db/StepMapper.php | 18 ++++++++++++++++++ lib/Service/DocumentService.php | 4 ++++ 3 files changed, 40 insertions(+), 1 deletion(-) diff --git a/lib/Cron/Cleanup.php b/lib/Cron/Cleanup.php index aadcb115a9e..7a83a3a0fc1 100644 --- a/lib/Cron/Cleanup.php +++ b/lib/Cron/Cleanup.php @@ -9,6 +9,7 @@ namespace OCA\Text\Cron; +use OCA\Text\Exception\DocumentHasUnsavedChangesException; use OCA\Text\Service\AttachmentService; use OCA\Text\Service\DocumentService; use OCA\Text\Service\SessionService; @@ -17,6 +18,8 @@ use Psr\Log\LoggerInterface; class Cleanup extends TimedJob { + private const ABANDONED_UNSAVED_CHANGES_AGE = 30 * 24 * 60 * 60; + public function __construct( ITimeFactory $time, private readonly SessionService $sessionService, @@ -34,7 +37,21 @@ public function __construct( protected function run($argument): void { $this->logger->debug('Run cleanup job for text documents'); foreach ($this->documentService->getAllWithNoActiveSession() as $document) { - $this->attachmentService->cleanupAttachments($document->getId()); + $documentId = $document->getId(); + try { + $this->documentService->resetDocument($documentId); + } catch (DocumentHasUnsavedChangesException) { + $lastStepTime = $this->documentService->getLatestStepTimestamp($documentId); + if ($lastStepTime === null || $lastStepTime >= $this->time->getTime() - self::ABANDONED_UNSAVED_CHANGES_AGE) { + continue; + } + $this->documentService->resetDocument($documentId, true); + $this->logger->warning('Force reset document with abandoned unsaved changes', [ + 'documentId' => $documentId, + 'lastStepTime' => $lastStepTime, + ]); + } + $this->attachmentService->cleanupAttachments($documentId); } $this->logger->debug('Run cleanup job for text sessions'); diff --git a/lib/Db/StepMapper.php b/lib/Db/StepMapper.php index 26339b0912b..637830a159e 100644 --- a/lib/Db/StepMapper.php +++ b/lib/Db/StepMapper.php @@ -56,6 +56,24 @@ public function getLatestVersion(int $documentId): ?int { return $data['id']; } + public function getLatestTimestamp(int $documentId): ?int { + $qb = $this->db->getQueryBuilder(); + $result = $qb->select('timestamp') + ->from($this->getTableName()) + ->where($qb->expr()->eq('document_id', $qb->createNamedParameter($documentId))) + ->setMaxResults(1) + ->orderBy('id', 'DESC') + ->executeQuery(); + + $data = $result->fetch(); + $result->closeCursor(); + if ($data === false) { + return null; + } + + return (int)$data['timestamp']; + } + public function getBeforeVersion(int $documentId, int $version, int $offset): int { $qb = $this->db->getQueryBuilder(); $result = $qb->select('id') diff --git a/lib/Service/DocumentService.php b/lib/Service/DocumentService.php index 91e510b08b4..982342ba3cc 100644 --- a/lib/Service/DocumentService.php +++ b/lib/Service/DocumentService.php @@ -428,6 +428,10 @@ public function autosave(Document $document, File $file, int $version, string $a return $document; } + public function getLatestStepTimestamp(int $documentId): ?int { + return $this->stepMapper->getLatestTimestamp($documentId); + } + /** * @throws DocumentHasUnsavedChangesException * @throws Exception