Skip to content

Commit b783280

Browse files
Merge pull request #61553 from nextcloud/backport/59857/stable34
[stable34] fix: track time spent in recursive markOrRun calls
2 parents f06a9f3 + 786b65f commit b783280

2 files changed

Lines changed: 42 additions & 7 deletions

File tree

apps/files_sharing/lib/Listener/SharesUpdatedListener.php

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,11 @@ class SharesUpdatedListener implements IEventListener {
4343
private float $cutOffMarkTime;
4444

4545
/**
46-
* The total amount of time we've spent so far processing updates
46+
* Timestamp marking the first time this listener was triggered, used to
47+
* determine if we should update the share date immediately or just mark the
48+
* users for refresh.
4749
*/
48-
private float $updatedTime = 0.0;
50+
private ?float $firstRun = null;
4951

5052
public function __construct(
5153
private readonly IManager $shareManager,
@@ -128,14 +130,15 @@ public function handle(Event $event): void {
128130
}
129131

130132
private function markOrRun(IUser $user, callable $callback): void {
131-
$start = floatval($this->clock->now()->format('U.u'));
132-
if ($this->cutOffMarkTime === -1.0 || $this->updatedTime < $this->cutOffMarkTime) {
133+
$now = (float)$this->clock->now()->format('U.u');
134+
$this->firstRun ??= $now;
135+
$elapsed = $now - $this->firstRun;
136+
137+
if ($this->cutOffMarkTime === -1.0 || $elapsed < $this->cutOffMarkTime) {
133138
$callback();
134139
} else {
135140
$this->markUserForRefresh($user);
136141
}
137-
$end = floatval($this->clock->now()->format('U.u'));
138-
$this->updatedTime += $end - $start;
139142
}
140143

141144
private function updateOrMarkUser(IUser $user): void {

apps/files_sharing/tests/SharesUpdatedListenerTest.php

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ class SharesUpdatedListenerTest extends \Test\TestCase {
3939
private LoggerInterface&MockObject $logger;
4040
private $clockFn;
4141

42+
private int $time = 0;
43+
4244
protected function setUp(): void {
4345
parent::setUp();
4446

@@ -50,7 +52,7 @@ protected function setUp(): void {
5052
$this->userConfig = new MockUserConfig();
5153
$this->clock = $this->createMock(ClockInterface::class);
5254
$this->clockFn = function () {
53-
return new \DateTimeImmutable('@0');
55+
return new \DateTimeImmutable("@{$this->time}");
5456
};
5557
$this->clock->method('now')
5658
->willReturnCallback(function () {
@@ -161,6 +163,36 @@ public static function shareMarkAfterTimeProvider(): array {
161163
];
162164
}
163165

166+
public function testCutoffSpansMultipleHandleInvocations(): void {
167+
$share = $this->createMock(IShare::class);
168+
$user1 = $this->createUser('user1', '');
169+
170+
$this->manager->method('getUsersForShare')
171+
->willReturn([$user1]);
172+
173+
$event = new ShareCreatedEvent($share);
174+
$this->sharesUpdatedListener->setCutOffMarkTime(4);
175+
176+
// First handle at t=0: firstRun=0, elapsed=0 < 0.5 → callback runs
177+
$this->shareRecipientUpdater
178+
->expects($this->exactly(2))
179+
->method('updateForAddedShare');
180+
181+
$this->assertFalse(
182+
$this->userConfig->getValueBool($user1->getUID(), 'files_sharing', ConfigLexicon::USER_NEEDS_SHARE_REFRESH)
183+
);
184+
185+
$this->sharesUpdatedListener->handle($event);
186+
$this->time = 1;
187+
$this->sharesUpdatedListener->handle($event);
188+
$this->time = 4;
189+
$this->sharesUpdatedListener->handle($event);
190+
191+
$this->assertTrue(
192+
$this->userConfig->getValueBool($user1->getUID(), 'files_sharing', ConfigLexicon::USER_NEEDS_SHARE_REFRESH)
193+
);
194+
}
195+
164196
#[DataProvider('shareMarkAfterTimeProvider')]
165197
public function testShareMarkAfterTime(float $cutOff, int $expectedCount) {
166198
$share = $this->createMock(IShare::class);

0 commit comments

Comments
 (0)