From 678ec844e25732ba3ec37924f0b37ffaf3373b84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Wed, 8 Apr 2026 22:26:27 +0200 Subject: [PATCH] Add service to clean expired locks and related tests - Introduced `CleanOldLock` service to remove expired locks older than 24 hours. - Added `removeExpiredBefore` method in `StoredObjectLockRepository` for efficient deletion of expired locks. - Created `CleanOldLockTest` to verify the cleaning service functionality using `MockClock`. --- .../Repository/StoredObjectLockRepository.php | 40 +++++++++++++ .../Service/Lock/CleanOldLock.php | 33 +++++++++++ .../Tests/Service/Lock/CleanOldLockTest.php | 57 +++++++++++++++++++ 3 files changed, 130 insertions(+) create mode 100644 src/Bundle/ChillDocStoreBundle/Repository/StoredObjectLockRepository.php create mode 100644 src/Bundle/ChillDocStoreBundle/Service/Lock/CleanOldLock.php create mode 100644 src/Bundle/ChillDocStoreBundle/Tests/Service/Lock/CleanOldLockTest.php diff --git a/src/Bundle/ChillDocStoreBundle/Repository/StoredObjectLockRepository.php b/src/Bundle/ChillDocStoreBundle/Repository/StoredObjectLockRepository.php new file mode 100644 index 000000000..2a0424f58 --- /dev/null +++ b/src/Bundle/ChillDocStoreBundle/Repository/StoredObjectLockRepository.php @@ -0,0 +1,40 @@ + + */ +class StoredObjectLockRepository extends ServiceEntityRepository +{ + public function __construct(ManagerRegistry $manager) + { + parent::__construct($manager, StoredObjectLock::class); + } + + public function removeExpiredBefore(\DateTimeImmutable $dateTime): void + { + $qb = $this->createQueryBuilder('sol'); + + $qb->delete() + ->where($qb->expr()->lt('sol.expireAt', ':at')) + ->andWhere($qb->expr()->isNotNull('sol.expireAt')) + ->setParameter('at', $dateTime, Types::DATETIMETZ_IMMUTABLE) + ->getQuery() + ->execute(); + } +} diff --git a/src/Bundle/ChillDocStoreBundle/Service/Lock/CleanOldLock.php b/src/Bundle/ChillDocStoreBundle/Service/Lock/CleanOldLock.php new file mode 100644 index 000000000..f01378c64 --- /dev/null +++ b/src/Bundle/ChillDocStoreBundle/Service/Lock/CleanOldLock.php @@ -0,0 +1,33 @@ +cleanBefore = new \DateInterval('PT24H'); + } + + public function __invoke(): void + { + $before = $this->clock->now()->sub($this->cleanBefore); + $this->storedObjectLockRepository->removeExpiredBefore($before); + } +} diff --git a/src/Bundle/ChillDocStoreBundle/Tests/Service/Lock/CleanOldLockTest.php b/src/Bundle/ChillDocStoreBundle/Tests/Service/Lock/CleanOldLockTest.php new file mode 100644 index 000000000..71acce488 --- /dev/null +++ b/src/Bundle/ChillDocStoreBundle/Tests/Service/Lock/CleanOldLockTest.php @@ -0,0 +1,57 @@ + + */ + private ObjectProphecy $repository; + + private CleanOldLock $service; + + protected function setUp(): void + { + $this->clock = new MockClock('2024-01-02 12:00:00'); + $this->repository = $this->prophesize(StoredObjectLockRepository::class); + $this->service = new CleanOldLock( + $this->repository->reveal(), + $this->clock + ); + } + + public function testInvoke(): void + { + $expectedBefore = $this->clock->now()->sub(new \DateInterval('PT24H')); + + $this->repository->removeExpiredBefore($expectedBefore)->shouldBeCalled(); + + ($this->service)(); + } +}