From 860e4c23209c4e1eae99700e3608192fb6b8a624 Mon Sep 17 00:00:00 2001 From: Louis Chemineau Date: Thu, 13 Oct 2022 17:46:37 +0200 Subject: [PATCH] Listen to cache event for managing metadata Signed-off-by: Louis Chemineau --- core/Application.php | 11 ++--- lib/private/Metadata/FileEventListener.php | 55 +++++++--------------- lib/private/ServerContainer.php | 1 + 3 files changed, 22 insertions(+), 45 deletions(-) diff --git a/core/Application.php b/core/Application.php index 749f2d176d440..cb2c08e792472 100644 --- a/core/Application.php +++ b/core/Application.php @@ -52,9 +52,8 @@ use OC\TagManager; use OCP\AppFramework\App; use OCP\EventDispatcher\IEventDispatcher; -use OCP\Files\Events\Node\NodeDeletedEvent; -use OCP\Files\Events\Node\NodeWrittenEvent; -use OCP\Files\Events\NodeRemovedFromCache; +use OCP\Files\Cache\CacheEntryInsertedEvent; +use OCP\Files\Cache\CacheEntryRemovedEvent; use OCP\IDBConnection; use OCP\User\Events\BeforeUserDeletedEvent; use OCP\User\Events\UserDeletedEvent; @@ -327,11 +326,9 @@ function (GenericEvent $event) use ($container) { $config = $container->get(IConfig::class); if ($config->getSystemValueBool('enable_file_metadata', true)) { /** @psalm-suppress InvalidArgument */ - $eventDispatcher->addServiceListener(NodeDeletedEvent::class, FileEventListener::class); + $eventDispatcher->addServiceListener(CacheEntryRemovedEvent::class, FileEventListener::class); /** @psalm-suppress InvalidArgument */ - $eventDispatcher->addServiceListener(NodeRemovedFromCache::class, FileEventListener::class); - /** @psalm-suppress InvalidArgument */ - $eventDispatcher->addServiceListener(NodeWrittenEvent::class, FileEventListener::class); + $eventDispatcher->addServiceListener(CacheEntryInsertedEvent::class, FileEventListener::class); } // Tags diff --git a/lib/private/Metadata/FileEventListener.php b/lib/private/Metadata/FileEventListener.php index 162e85ff3aa9d..92ff98f326c6a 100644 --- a/lib/private/Metadata/FileEventListener.php +++ b/lib/private/Metadata/FileEventListener.php @@ -21,17 +21,13 @@ namespace OC\Metadata; -use OC\Files\Filesystem; use OCP\EventDispatcher\Event; use OCP\EventDispatcher\IEventListener; -use OCP\Files\Events\Node\NodeDeletedEvent; -use OCP\Files\Events\Node\NodeWrittenEvent; -use OCP\Files\Events\NodeRemovedFromCache; +use OCP\Files\Cache\CacheEntryInsertedEvent; +use OCP\Files\Cache\CacheEntryRemovedEvent; use OCP\Files\File; use OCP\Files\Node; use OCP\Files\NotFoundException; -use OCP\Files\FileInfo; -use Psr\Log\LoggerInterface; /** * @template-implements IEventListener @@ -40,15 +36,17 @@ */ class FileEventListener implements IEventListener { private IMetadataManager $manager; - private LoggerInterface $logger; - public function __construct(IMetadataManager $manager, LoggerInterface $logger) { + public function __construct(IMetadataManager $manager) { $this->manager = $manager; - $this->logger = $logger; } - private function shouldExtractMetadata(Node $node): bool { + private function shouldExtractMetadata(?Node $node): bool { try { + if ($node === null) { + return false; + } + if ($node->getMimetype() === 'httpd/unix-directory') { return false; } @@ -69,41 +67,22 @@ private function isCorrectPath(string $path): bool { } public function handle(Event $event): void { - if ($event instanceof NodeRemovedFromCache) { - if (!$this->isCorrectPath($event->getPath())) { - // Don't listen to paths for which we don't extract metadata - return; - } - $view = Filesystem::getView(); - if (!$view) { - // Should not happen since a scan in the user folder should setup - // the file system. - $e = new \Exception(); // don't trigger, just get backtrace - $this->logger->error('Detecting deletion of a file with possible metadata but file system setup is not setup', [ - 'exception' => $e, - 'app' => 'metadata' - ]); - return; - } - $info = $view->getFileInfo($event->getPath()); - if ($info && $info->getType() === FileInfo::TYPE_FILE) { - $this->manager->clearMetadata($info->getId()); - } - } + if ($event instanceof CacheEntryRemovedEvent) { + $owner = $event->getStorage()->getOwner($event->getPath()); + $node = $this->rootFolder->getUserFolder($owner)->getById($event->getFileId())[0]; - if ($event instanceof NodeDeletedEvent) { - $node = $event->getNode(); if ($this->shouldExtractMetadata($node)) { - /** @var File $node */ - $this->manager->clearMetadata($event->getNode()->getId()); + $this->manager->clearMetadata($event->getFileId()); } } - if ($event instanceof NodeWrittenEvent) { - $node = $event->getNode(); + if ($event instanceof CacheEntryInsertedEvent) { + $owner = $event->getStorage()->getOwner($event->getPath()); + $node = $this->rootFolder->getUserFolder($owner)->getById($event->getFileId())[0]; + if ($this->shouldExtractMetadata($node)) { /** @var File $node */ - $this->manager->generateMetadata($event->getNode(), false); + $this->manager->generateMetadata($node, false); } } } diff --git a/lib/private/ServerContainer.php b/lib/private/ServerContainer.php index d6bec7526b731..32ff5545d8d53 100644 --- a/lib/private/ServerContainer.php +++ b/lib/private/ServerContainer.php @@ -144,6 +144,7 @@ public function query(string $name, bool $autoload = true) { try { return $appContainer->queryNoFallback($name); } catch (QueryException $e) { + $e = $e; // Didn't find the service or the respective app container, // ignore it and fall back to the core container. }