Skip to content

Commit 861b9ea

Browse files
committed
fix(FileSystemListenerJob): Prevent OOM
by working per user and tearing down FS in between Signed-off-by: Marcel Klehr <mklehr@gmx.net>
1 parent 84833e9 commit 861b9ea

File tree

1 file changed

+41
-29
lines changed

1 file changed

+41
-29
lines changed

lib/BackgroundJobs/FileSystemListenerJob.php

Lines changed: 41 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -63,43 +63,55 @@ protected function run($argument): void {
6363
return;
6464
}
6565

66+
$eventsByUser = [];
6667
foreach ($fsEvents as $fsEvent) {
67-
$this->diagnosticService->sendHeartbeat(static::class, $this->getId());
68-
69-
try {
70-
$node = current($this->rootFolder->getUserFolder($fsEvent->getUserId())->getById($fsEvent->getNodeId()));
71-
} catch (\Exception $e) {
72-
$this->logger->warning('Error retrieving node for fs event "' . $fsEvent->getType() . '": ' . $e->getMessage(), ['exception' => $e]);
73-
$node = false;
68+
if (!isset($eventsByUser[$fsEvent->getUserId()])) {
69+
$eventsByUser[$fsEvent->getUserId()] = [];
7470
}
75-
if ($node === false) {
76-
$this->logger->warning('Node with ID ' . $fsEvent->getNodeId() . ' not found for fs event "' . $fsEvent->getType() . '"');
71+
$eventsByUser[$fsEvent->getUserId()][] = $fsEvent;
72+
}
73+
74+
foreach ($eventsByUser as $userId => $events) {
75+
foreach ($events as $fsEvent) {
76+
$this->diagnosticService->sendHeartbeat(static::class, $this->getId());
77+
78+
try {
79+
$node = current($this->rootFolder->getUserFolder($fsEvent->getUserId())->getById($fsEvent->getNodeId()));
80+
} catch (\Exception $e) {
81+
$this->logger->warning('Error retrieving node for fs event "' . $fsEvent->getType() . '": ' . $e->getMessage(), ['exception' => $e]);
82+
$node = false;
83+
}
84+
if ($node === false) {
85+
$this->logger->warning('Node with ID ' . $fsEvent->getNodeId() . ' not found for fs event "' . $fsEvent->getType() . '"');
86+
try {
87+
$this->fsEventMapper->delete($fsEvent);
88+
} catch (Exception $e) {
89+
$this->logger->warning('Error deleting fs event "' . $fsEvent->getType() . '": ' . $e->getMessage(), ['exception' => $e]);
90+
}
91+
continue;
92+
}
93+
94+
try {
95+
switch ($fsEvent->getTypeObject()) {
96+
case FsEventType::CREATE:
97+
$this->fsEventService->onInsert($node);
98+
break;
99+
case FsEventType::ACCESS_UPDATE_DECL:
100+
$this->fsEventService->onAccessUpdateDecl($node);
101+
break;
102+
}
103+
$this->diagnosticService->sendHeartbeat(static::class, $this->getId());
104+
} catch (\Throwable $e) {
105+
$this->logger->warning('Error handling fs event "' . $fsEvent->getType() . '": ' . $e->getMessage(), ['exception' => $e]);
106+
}
77107
try {
78108
$this->fsEventMapper->delete($fsEvent);
79109
} catch (Exception $e) {
80110
$this->logger->warning('Error deleting fs event "' . $fsEvent->getType() . '": ' . $e->getMessage(), ['exception' => $e]);
81111
}
82-
continue;
83-
}
84-
85-
try {
86-
switch ($fsEvent->getTypeObject()) {
87-
case FsEventType::CREATE:
88-
$this->fsEventService->onInsert($node);
89-
break;
90-
case FsEventType::ACCESS_UPDATE_DECL:
91-
$this->fsEventService->onAccessUpdateDecl($node);
92-
break;
93-
}
94-
$this->diagnosticService->sendHeartbeat(static::class, $this->getId());
95-
} catch (\Throwable $e) {
96-
$this->logger->warning('Error handling fs event "' . $fsEvent->getType() . '": ' . $e->getMessage(), ['exception' => $e]);
97-
}
98-
try {
99-
$this->fsEventMapper->delete($fsEvent);
100-
} catch (Exception $e) {
101-
$this->logger->warning('Error deleting fs event "' . $fsEvent->getType() . '": ' . $e->getMessage(), ['exception' => $e]);
102112
}
113+
// Tear down to avoid memory leaks
114+
\OC_Util::tearDownFS();
103115
}
104116
} finally {
105117
$this->diagnosticService->sendJobEnd(static::class, $this->getId());

0 commit comments

Comments
 (0)