Skip to content

Commit a525a64

Browse files
authored
Merge pull request #897 from nextcloud/fix/lockDeletion
Fix/lock deletion
2 parents a441e65 + 42a75c8 commit a525a64

File tree

6 files changed

+36
-8
lines changed

6 files changed

+36
-8
lines changed

lib/Cron/Unlock.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,10 @@ public function __construct(ITimeFactory $timeFactory, LockService $lockService)
2525
}
2626

2727
protected function run($argument): void {
28-
$this->manageTimeoutLock();
28+
$this->deleteExpiredLocks();
2929
}
3030

31-
private function manageTimeoutLock(): void {
32-
$this->lockService->removeLocks($this->lockService->getDeprecatedLocks());
31+
private function deleteExpiredLocks(): void {
32+
$this->lockService->removeLocks($this->lockService->getDeprecatedLocks(1000));
3333
}
3434
}

lib/Db/CoreQueryBuilder.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ public function limitToFileId(int $fileId): void {
2929
* @param array $ids
3030
*/
3131
public function limitToIds(array $ids): void {
32-
$this->limitArray('id', $ids);
32+
$this->limitInArray('id', $ids);
3333
}
3434

3535
public function limitToFileIds(array $ids): void {

lib/Db/LocksRequest.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,16 +123,21 @@ public function getAll(): array {
123123

124124
/**
125125
* @param int $timeout in minutes
126+
* @param int $limit how many locks to retrieve (0 for all, default)
126127
*
127128
* @return FileLock[]
128129
* @throws Exception
129130
*/
130-
public function getLocksOlderThan(int $timeout): array {
131+
public function getLocksOlderThan(int $timeout, int $limit = 0): array {
131132
$now = \OC::$server->get(ITimeFactory::class)->getTime();
132133
$oldCreationTime = $now - $timeout * 60;
133134
$qb = $this->getLocksSelectSql();
134135
$qb->andWhere($qb->expr()->lt('l.creation', $qb->createNamedParameter($oldCreationTime, IQueryBuilder::PARAM_INT)));
135136

137+
if ($limit !== 0) {
138+
$qb->setMaxResults($limit);
139+
}
140+
136141
return $this->getLocksFromRequest($qb);
137142
}
138143
}

lib/Service/LockService.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -274,9 +274,11 @@ public function unlockFile(int $fileId, string $userId, bool $force = false, int
274274

275275

276276
/**
277+
* @param int $limit how many locks to retrieve (0 for all, default)
278+
*
277279
* @return FileLock[]
278280
*/
279-
public function getDeprecatedLocks(): array {
281+
public function getDeprecatedLocks(int $limit = 0): array {
280282
$timeout = (int)$this->configService->getAppValue(ConfigService::LOCK_TIMEOUT);
281283
if ($timeout === 0) {
282284
$this->logger->notice(
@@ -286,7 +288,7 @@ public function getDeprecatedLocks(): array {
286288
}
287289

288290
try {
289-
$locks = $this->locksRequest->getLocksOlderThan($timeout);
291+
$locks = $this->locksRequest->getLocksOlderThan($timeout, $limit);
290292
} catch (Exception $e) {
291293
$this->logger->warning('Failed to get locks older then timeout', ['exception' => $e]);
292294
return [];

lib/Tools/Db/ExtendedQueryBuilder.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ public function limitToId(int $id): void {
101101
* @param array $ids
102102
*/
103103
public function limitToIds(array $ids): void {
104-
$this->limitArray('id', $ids);
104+
$this->limitInArray('id', $ids);
105105
}
106106

107107
/**

tests/Feature/LockFeatureTest.php

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,27 @@ public function testExpiredLocksAreDeprecated() {
216216
self::assertNotEmpty($deprecated);
217217
}
218218

219+
public function testRemoveLocks(): void {
220+
$service = \OCP\Server::get(LockService::class);
221+
\OCP\Server::get(IConfig::class)->setAppValue(Application::APP_ID, ConfigService::LOCK_TIMEOUT, 30);
222+
$file = $this->loginAndGetUserFolder(self::TEST_USER1)->newFile('test-expired-lock-is-deprecated', 'AAA');
223+
$lock1 = $this->lockManager->lock(new LockContext($file, ILock::TYPE_USER, self::TEST_USER1));
224+
$file2 = $this->loginAndGetUserFolder(self::TEST_USER1)->newFile('test-expired-lock-is-deprecated-2', 'AAA');
225+
$lock2 = $this->lockManager->lock(new LockContext($file2, ILock::TYPE_USER, self::TEST_USER1));
226+
$this->toTheFuture(3600);
227+
$mapToTokens = fn (ILock $lock) => $lock->getToken();
228+
$deprecated = array_map($mapToTokens, $service->getDeprecatedLocks());
229+
230+
self::assertContains($lock1->getToken(), $deprecated);
231+
self::assertContains($lock2->getToken(), $deprecated);
232+
233+
$service->removeLocks([$lock1, $lock2]);
234+
$deprecated = array_map($mapToTokens, $service->getDeprecatedLocks());
235+
236+
self::assertNotContains($lock1->getToken(), $deprecated);
237+
self::assertNotContains($lock2->getToken(), $deprecated);
238+
}
239+
219240
public function testLockUserInfinite() {
220241
\OCP\Server::get(IConfig::class)->setAppValue(Application::APP_ID, ConfigService::LOCK_TIMEOUT, 0);
221242
$file = $this->loginAndGetUserFolder(self::TEST_USER1)

0 commit comments

Comments
 (0)