22
33namespace OCA \Recognize \Service ;
44
5+ use OC \Files \SetupManager ;
6+ use OC \User \NoUserException ;
57use OCA \Recognize \BackgroundJobs \ClusterFacesJob ;
68use OCA \Recognize \Classifiers \Audio \MusicnnClassifier ;
79use OCA \Recognize \Classifiers \Images \ClusteringFaceClassifier ;
2527use OCP \Files \IRootFolder ;
2628use OCP \Files \Node ;
2729use OCP \Files \NotFoundException ;
30+ use OCP \Files \NotPermittedException ;
2831use Psr \Log \LoggerInterface ;
2932
3033final class FsActionService {
@@ -72,10 +75,25 @@ public function processActionsByClass(string $className): void {
7275 * @param array<FsCreation|FsDeletion|FsMove|FsAccessUpdate> $actions
7376 */
7477 public function processActions (array $ actions ): void {
78+ $ lastUserId = null ;
7579 foreach ($ actions as $ action ) {
7680 switch ($ action ::class) {
7781 case FsCreation::class:
78- $ rootNode = $ this ->rootFolder ->getFirstNodeById ($ action ->getRootId ());
82+ $ this ->logger ->debug ('Processing FsCreation action for storageId ' . $ action ->getStorageId () . ' and rootId ' . $ action ->getRootId ());
83+ // Tear down to avoid memory leaks and OOMs
84+ // The fs event table is sorted by user ID, so we only need to tear down when the user ID changes
85+ $ actionUserId = $ action ->getUserId ();
86+ if ($ actionUserId !== $ lastUserId ) {
87+ $ lastUserId = $ actionUserId ;
88+ $ setupManager = \OCP \Server::get (SetupManager::class);
89+ $ setupManager ->tearDown ();
90+ }
91+ try {
92+ $ rootNode = $ this ->rootFolder ->getUserFolder ($ actionUserId )->getFirstNodeById ($ action ->getRootId ());
93+ } catch (NotPermittedException |NoUserException $ e ) {
94+ $ this ->logger ->warning ('Failed to find root node for creation action: ' . $ e ->getMessage (), ['exception ' => $ e ]);
95+ break ;
96+ }
7997 if ($ rootNode === null ) {
8098 $ this ->logger ->info ('Failed to find root node for creation action ' , ['nodeId ' => $ action ->getRootId (), 'storageId ' => $ action ->getStorageId ()]);
8199 break ;
@@ -88,16 +106,19 @@ public function processActions(array $actions): void {
88106 break ;
89107
90108 case FsDeletion::class:
109+ $ this ->logger ->debug ('Processing FsDeletion action for nodeId ' . $ action ->getNodeId ());
91110 $ this ->onDeletion ($ action ->getNodeId ()); // todo add mimetypes filter here
92111 break ;
93112 case FsAccessUpdate::class:
113+ $ this ->logger ->debug ('Processing FsAccessUpdate action for storageId ' . $ action ->getStorageId () . ' and rootId ' . $ action ->getRootId ());
94114 try {
95115 $ this ->onAccessUpdate ($ action ->getStorageId (), $ action ->getRootId ());
96116 } catch (Exception |InvalidPathException |NotFoundException $ e ) {
97117 $ this ->logger ->warning ('Failed to process access update action: ' . $ e ->getMessage () . ' Continuing. ' , ['exception ' => $ e ]);
98118 }
99119 break ;
100120 case FsMove::class:
121+ $ this ->logger ->debug ('Processing FsMove action for nodeId ' . $ action ->getNodeId ());
101122 $ node = $ this ->rootFolder ->getFirstNodeById ($ action ->getNodeId ());
102123 if ($ node === null ) {
103124 $ this ->logger ->info ('Failed to find root node for move action ' , ['nodeId ' => $ action ->getNodeId ()]);
@@ -202,12 +223,14 @@ public function onCreation(Node $node, bool $recurse = true, ?array $mimeTypes =
202223 $ queueFile = new QueueFile ();
203224 $ storageId = $ node ->getMountPoint ()->getNumericStorageId ();
204225 if ($ storageId === null ) {
226+ $ this ->logger ->debug ('Storage ID is null for node ' . $ node ->getId ());
205227 return ;
206228 }
207229 $ queueFile ->setStorageId ($ storageId );
208230 $ queueFile ->setRootId ($ node ->getMountPoint ()->getStorageRootId ());
209231
210232 if ($ this ->isFileIgnored ($ node )) {
233+ $ this ->logger ->debug ('File ignored, skipping: ' . $ node ->getId ());
211234 return ;
212235 }
213236
0 commit comments