Skip to content

Commit f5638ca

Browse files
committed
Listen to cache event for managing metadata
Signed-off-by: Louis Chemineau <[email protected]>
1 parent 94ded14 commit f5638ca

File tree

2 files changed

+41
-68
lines changed

2 files changed

+41
-68
lines changed

core/Application.php

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,9 @@
5252
use OC\TagManager;
5353
use OCP\AppFramework\App;
5454
use OCP\EventDispatcher\IEventDispatcher;
55-
use OCP\Files\Events\Node\NodeDeletedEvent;
56-
use OCP\Files\Events\Node\NodeWrittenEvent;
57-
use OCP\Files\Events\NodeRemovedFromCache;
55+
use OCP\Files\Cache\CacheEntryInsertedEvent;
56+
use OCP\Files\Cache\CacheEntryRemovedEvent;
57+
use OCP\Files\Cache\CacheEntryUpdatedEvent;
5858
use OCP\IDBConnection;
5959
use OCP\User\Events\BeforeUserDeletedEvent;
6060
use OCP\User\Events\UserDeletedEvent;
@@ -327,11 +327,11 @@ function (GenericEvent $event) use ($container) {
327327
$config = $container->get(IConfig::class);
328328
if ($config->getSystemValueBool('enable_file_metadata', true)) {
329329
/** @psalm-suppress InvalidArgument */
330-
$eventDispatcher->addServiceListener(NodeDeletedEvent::class, FileEventListener::class);
330+
$eventDispatcher->addServiceListener(CacheEntryRemovedEvent::class, FileEventListener::class);
331331
/** @psalm-suppress InvalidArgument */
332-
$eventDispatcher->addServiceListener(NodeRemovedFromCache::class, FileEventListener::class);
332+
$eventDispatcher->addServiceListener(CacheEntryInsertedEvent::class, FileEventListener::class);
333333
/** @psalm-suppress InvalidArgument */
334-
$eventDispatcher->addServiceListener(NodeWrittenEvent::class, FileEventListener::class);
334+
$eventDispatcher->addServiceListener(CacheEntryUpdatedEvent::class, FileEventListener::class);
335335
}
336336

337337
// Tags

lib/private/Metadata/FileEventListener.php

Lines changed: 35 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -21,89 +21,62 @@
2121

2222
namespace OC\Metadata;
2323

24-
use OC\Files\Filesystem;
2524
use OCP\EventDispatcher\Event;
2625
use OCP\EventDispatcher\IEventListener;
27-
use OCP\Files\Events\Node\NodeDeletedEvent;
28-
use OCP\Files\Events\Node\NodeWrittenEvent;
29-
use OCP\Files\Events\NodeRemovedFromCache;
26+
use OCP\Files\Cache\CacheEntryInsertedEvent;
27+
use OCP\Files\Cache\CacheEntryRemovedEvent;
28+
use OCP\Files\Cache\CacheEntryUpdatedEvent;
29+
use OCP\Files\Cache\ICacheEvent;
3030
use OCP\Files\File;
31-
use OCP\Files\Node;
32-
use OCP\Files\NotFoundException;
33-
use OCP\Files\FileInfo;
34-
use Psr\Log\LoggerInterface;
31+
use OCP\Files\IRootFolder;
3532

3633
/**
37-
* @template-implements IEventListener<NodeRemovedFromCache>
38-
* @template-implements IEventListener<NodeDeletedEvent>
39-
* @template-implements IEventListener<NodeWrittenEvent>
34+
* @template-implements IEventListener<CacheEntryRemovedEvent>
35+
* @template-implements IEventListener<CacheEntryInsertedEvent>
4036
*/
4137
class FileEventListener implements IEventListener {
38+
private IRootFolder $rootFolder;
4239
private IMetadataManager $manager;
43-
private LoggerInterface $logger;
4440

45-
public function __construct(IMetadataManager $manager, LoggerInterface $logger) {
41+
public function __construct(
42+
IRootFolder $rootFolder,
43+
IMetadataManager $manager
44+
) {
45+
$this->rootFolder = $rootFolder;
4646
$this->manager = $manager;
47-
$this->logger = $logger;
48-
}
49-
50-
private function shouldExtractMetadata(Node $node): bool {
51-
try {
52-
if ($node->getMimetype() === 'httpd/unix-directory') {
53-
return false;
54-
}
55-
} catch (NotFoundException $e) {
56-
return false;
57-
}
58-
if ($node->getSize(false) <= 0) {
59-
return false;
60-
}
61-
62-
$path = $node->getPath();
63-
return $this->isCorrectPath($path);
6447
}
6548

6649
private function isCorrectPath(string $path): bool {
6750
// TODO make this more dynamic, we have the same issue in other places
68-
return !str_starts_with($path, 'appdata_') && !str_starts_with($path, 'files_versions/') && !str_starts_with($path, 'files_trashbin/');
51+
return !str_starts_with($path, 'appdata_') && !str_starts_with($path, 'files_versions/');
6952
}
7053

54+
/**
55+
* @param ICacheEvent $event
56+
*/
7157
public function handle(Event $event): void {
72-
if ($event instanceof NodeRemovedFromCache) {
73-
if (!$this->isCorrectPath($event->getPath())) {
74-
// Don't listen to paths for which we don't extract metadata
75-
return;
76-
}
77-
$view = Filesystem::getView();
78-
if (!$view) {
79-
// Should not happen since a scan in the user folder should setup
80-
// the file system.
81-
$e = new \Exception(); // don't trigger, just get backtrace
82-
$this->logger->error('Detecting deletion of a file with possible metadata but file system setup is not setup', [
83-
'exception' => $e,
84-
'app' => 'metadata'
85-
]);
86-
return;
87-
}
88-
$info = $view->getFileInfo($event->getPath());
89-
if ($info && $info->getType() === FileInfo::TYPE_FILE) {
90-
$this->manager->clearMetadata($info->getId());
91-
}
58+
if ($event->getStorage()->is_dir($event->getPath())) {
59+
return;
9260
}
9361

94-
if ($event instanceof NodeDeletedEvent) {
95-
$node = $event->getNode();
96-
if ($this->shouldExtractMetadata($node)) {
97-
/** @var File $node */
98-
$this->manager->clearMetadata($event->getNode()->getId());
99-
}
62+
if (!$this->isCorrectPath($event->getPath())) {
63+
return;
64+
}
65+
66+
if ($event instanceof CacheEntryRemovedEvent) {
67+
$this->manager->clearMetadata($event->getFileId());
10068
}
10169

102-
if ($event instanceof NodeWrittenEvent) {
103-
$node = $event->getNode();
104-
if ($this->shouldExtractMetadata($node)) {
105-
/** @var File $node */
106-
$this->manager->generateMetadata($event->getNode(), false);
70+
if ($event instanceof CacheEntryInsertedEvent || $event instanceof CacheEntryUpdatedEvent) {
71+
if ($event->getStorage()->filesize($event->getPath()) <= 0) {
72+
return;
73+
}
74+
75+
$owner = $event->getStorage()->getOwner($event->getPath());
76+
$node = $this->rootFolder->getUserFolder($owner)->getById($event->getFileId())[0];
77+
78+
if ($node instanceof File) {
79+
$this->manager->generateMetadata($node, false);
10780
}
10881
}
10982
}

0 commit comments

Comments
 (0)