Skip to content

Commit c679e81

Browse files
committed
perf(dav): avoid repeated stack lookups for object etags
Signed-off-by: Jaggob <37583151+Jaggob@users.noreply.github.com>
1 parent 458a463 commit c679e81

4 files changed

Lines changed: 57 additions & 8 deletions

File tree

lib/DAV/CalendarObject.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,11 @@ public function getContentType() {
8181
}
8282

8383
public function getETag() {
84-
return '"' . md5($this->sourceItem->getLastModified() . '|' . $this->backend->getObjectRevisionFingerprint($this->sourceItem)) . '"';
84+
return '"' . md5($this->sourceItem->getLastModified() . '|' . $this->backend->getObjectRevisionFingerprint(
85+
$this->sourceItem,
86+
$this->calendar->getBoardId(),
87+
$this->calendar->getStackId()
88+
)) . '"';
8589
}
8690

8791
public function getSize() {

lib/DAV/DeckCalendarBackend.php

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -192,21 +192,32 @@ public function getCalendarRevisionFingerprint(int $boardId, ?int $stackId = nul
192192
/**
193193
* @param Card|Stack $sourceItem
194194
*/
195-
public function getObjectRevisionFingerprint($sourceItem): string {
195+
public function getObjectRevisionFingerprint($sourceItem, ?int $boardId = null, ?int $calendarStackId = null): string {
196196
$mode = $this->configService->getCalDavListMode();
197197
if (!($sourceItem instanceof Card)) {
198198
return $mode;
199199
}
200200

201-
try {
202-
$stack = $this->stackService->find($sourceItem->getStackId());
203-
$boardId = $stack->getBoardId();
204-
} catch (\Throwable $e) {
205-
return $mode;
201+
$stackId = $calendarStackId ?? $sourceItem->getStackId();
202+
$stack = null;
203+
204+
if ($mode === ConfigService::SETTING_CALDAV_LIST_MODE_LIST_AS_CATEGORY || $boardId === null) {
205+
try {
206+
$stack = $this->stackService->find($sourceItem->getStackId());
207+
$boardId ??= $stack->getBoardId();
208+
$stackId = $stack->getId();
209+
} catch (\Throwable $e) {
210+
return $mode;
211+
}
206212
}
207213

208-
$fingerprint = [$mode, 'stack:' . $stack->getId()];
214+
$fingerprint = [$mode, 'stack:' . $stackId];
209215
if ($mode === ConfigService::SETTING_CALDAV_LIST_MODE_LIST_AS_CATEGORY) {
216+
try {
217+
$stack ??= $this->stackService->find($sourceItem->getStackId());
218+
} catch (\Throwable $e) {
219+
return $mode;
220+
}
210221
$fingerprint[] = $stack->getTitle();
211222
$fingerprint[] = (string)$stack->getDeletedAt();
212223
}

tests/unit/DAV/CalendarObjectTest.php

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,4 +59,25 @@ public function testCardObjectAclKeepsWriteForEditors(): void {
5959

6060
$this->assertSame($expectedAcl, $calendarObject->getACL());
6161
}
62+
63+
public function testGetETagPassesCalendarContextToBackendFingerprint(): void {
64+
$calendar = $this->createMock(Calendar::class);
65+
$calendar->method('getBoardId')->willReturn(12);
66+
$calendar->method('getStackId')->willReturn(9);
67+
68+
$backend = $this->createMock(DeckCalendarBackend::class);
69+
70+
$card = $this->createMock(Card::class);
71+
$card->method('getCalendarObject')->willReturn(new VCalendar());
72+
$card->method('getLastModified')->willReturn(1234567890);
73+
74+
$backend->expects($this->once())
75+
->method('getObjectRevisionFingerprint')
76+
->with($card, 12, 9)
77+
->willReturn('fingerprint');
78+
79+
$calendarObject = new CalendarObject($calendar, 'card-7.ics', $backend, $card);
80+
81+
$this->assertSame('"' . md5('1234567890|fingerprint') . '"', $calendarObject->getETag());
82+
}
6283
}

tests/unit/DAV/DeckCalendarBackendTest.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1091,4 +1091,17 @@ public function testUpdateCardLimitsAutoCreatedLabelsPerSync(): void {
10911091

10921092
$this->backend->updateCalendarObject($sourceCard, $calendarData);
10931093
}
1094+
1095+
public function testGetObjectRevisionFingerprintUsesKnownBoardContextWithoutStackLookup(): void {
1096+
$card = new Card();
1097+
$card->setId(123);
1098+
$card->setStackId(42);
1099+
1100+
$this->stackService->expects($this->never())
1101+
->method('find');
1102+
1103+
$fingerprint = $this->backend->getObjectRevisionFingerprint($card, 12, 42);
1104+
1105+
$this->assertSame(ConfigService::SETTING_CALDAV_LIST_MODE_ROOT_TASKS . '|stack:42', $fingerprint);
1106+
}
10941107
}

0 commit comments

Comments
 (0)