Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nextcloud/server.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorJulius Härtl <jus@bitgrid.net>2022-08-12 19:22:52 +0300
committerJulius Härtl <jus@bitgrid.net>2022-08-31 17:20:06 +0300
commit31be855522fe68956cb38aaca2a9544c5a75f230 (patch)
tree210610271927db18bd109c1b07311926d1f70984 /lib
parent9d9c7f4b7557f7fa8dc5c5ad3925261a1efb966c (diff)
Implement reference provider based caching
Signed-off-by: Julius Härtl <jus@bitgrid.net>
Diffstat (limited to 'lib')
-rw-r--r--lib/private/Collaboration/Reference/FileReferenceProvider.php19
-rw-r--r--lib/private/Collaboration/Reference/LinkReferenceProvider.php18
-rw-r--r--lib/private/Collaboration/Reference/ReferenceManager.php29
-rw-r--r--lib/public/Collaboration/Reference/IReferenceProvider.php3
4 files changed, 56 insertions, 13 deletions
diff --git a/lib/private/Collaboration/Reference/FileReferenceProvider.php b/lib/private/Collaboration/Reference/FileReferenceProvider.php
index 9fb083f749c..b7c9bc9cd56 100644
--- a/lib/private/Collaboration/Reference/FileReferenceProvider.php
+++ b/lib/private/Collaboration/Reference/FileReferenceProvider.php
@@ -41,8 +41,13 @@ class FileReferenceProvider implements IReferenceProvider {
$this->userId = $userSession->getUser() ? $userSession->getUser()->getUID() : null;
}
+ public function matchReference(string $referenceText): bool {
+ return str_starts_with($referenceText, $this->urlGenerator->getAbsoluteURL('/index.php/f/'))
+ || str_starts_with($referenceText, $this->urlGenerator->getAbsoluteURL('/f/'));
+ }
+
public function resolveReference(string $referenceText): ?IReference {
- if (str_starts_with($referenceText, $this->urlGenerator->getAbsoluteURL('/index.php/f/')) || str_starts_with($referenceText, $this->urlGenerator->getAbsoluteURL('/f/'))) {
+ if ($this->matchReference($referenceText)) {
$reference = new Reference($referenceText);
try {
$this->fetchReference($reference);
@@ -62,6 +67,10 @@ class FileReferenceProvider implements IReferenceProvider {
* @throws \OC\User\NoUserException
*/
private function fetchReference(Reference $reference) {
+ if ($this->userId === null) {
+ throw new NotFoundException();
+ }
+
$fileId = str_replace($this->urlGenerator->getAbsoluteURL('/index.php/f/'), '', $reference->getId());
$fileId = str_replace($this->urlGenerator->getAbsoluteURL('/f/'), '', $fileId);
@@ -90,4 +99,12 @@ class FileReferenceProvider implements IReferenceProvider {
'preview-available' => false
]);
}
+
+ public function isGloballyCachable(): bool {
+ return false;
+ }
+
+ public function getCacheKey(string $referenceId): string {
+ return $this->userId;
+ }
}
diff --git a/lib/private/Collaboration/Reference/LinkReferenceProvider.php b/lib/private/Collaboration/Reference/LinkReferenceProvider.php
index b4c44344476..0f3ff5f6732 100644
--- a/lib/private/Collaboration/Reference/LinkReferenceProvider.php
+++ b/lib/private/Collaboration/Reference/LinkReferenceProvider.php
@@ -44,12 +44,16 @@ class LinkReferenceProvider implements IReferenceProvider {
$this->systemConfig = $systemConfig;
}
- public function resolveReference(string $referenceText): ?IReference {
+ public function matchReference(string $referenceText): bool {
if ($this->systemConfig->getValue('reference_opengraph', true) !== true) {
- return null;
+ return false;
}
- if (preg_match(self::URL_PATTERN, $referenceText)) {
+ return (bool)preg_match(self::URL_PATTERN, $referenceText);
+ }
+
+ public function resolveReference(string $referenceText): ?IReference {
+ if ($this->matchReference($referenceText)) {
$reference = new Reference($referenceText);
$this->fetchReference($reference);
return $reference;
@@ -87,4 +91,12 @@ class LinkReferenceProvider implements IReferenceProvider {
$reference->setImageUrl($object->images[0]->url);
}
}
+
+ public function isGloballyCachable(): bool {
+ return true;
+ }
+
+ public function getCacheKey(string $referenceId): string {
+ return '';
+ }
}
diff --git a/lib/private/Collaboration/Reference/ReferenceManager.php b/lib/private/Collaboration/Reference/ReferenceManager.php
index 6f0ef37198e..5cab10c0ef5 100644
--- a/lib/private/Collaboration/Reference/ReferenceManager.php
+++ b/lib/private/Collaboration/Reference/ReferenceManager.php
@@ -54,20 +54,31 @@ class ReferenceManager implements IReferenceManager {
}
public function resolveReference(string $referenceId): ?IReference {
- $cached = $this->cache->get($referenceId);
+ $matchedProvider = null;
+ foreach ($this->providers as $provider) {
+ $matchedProvider = $provider->matchReference($referenceId) ? $provider : null;
+ }
+
+ if ($matchedProvider === null) {
+ $matchedProvider = $this->linkReferenceProvider;
+ }
+
+ $cacheKey = md5(serialize([
+ $matchedProvider->isGloballyCachable() ? 0 : $matchedProvider->getCacheKey($referenceId),
+ $referenceId
+ ]));
+ $cached = $this->cache->get($cacheKey);
if ($cached) {
- // TODO: Figure out caching for references that depend on the viewer user
return Reference::fromCache($cached);
}
- foreach ($this->providers as $provider) {
- $reference = $provider->resolveReference($referenceId);
- if ($reference) {
- $this->cache->set($referenceId, Reference::toCache($reference), 60);
- return $reference;
- }
+
+ $reference = $matchedProvider->resolveReference($referenceId);
+ if ($reference) {
+ $this->cache->set($cacheKey, Reference::toCache($reference), 60);
+ return $reference;
}
- return $this->linkReferenceProvider->resolveReference($referenceId);
+ return null;
}
public function registerReferenceProvider(IReferenceProvider $provider): void {
diff --git a/lib/public/Collaboration/Reference/IReferenceProvider.php b/lib/public/Collaboration/Reference/IReferenceProvider.php
index 232874709c2..ff0bfc8ed47 100644
--- a/lib/public/Collaboration/Reference/IReferenceProvider.php
+++ b/lib/public/Collaboration/Reference/IReferenceProvider.php
@@ -23,5 +23,8 @@
namespace OCP\Collaboration\Reference;
interface IReferenceProvider {
+ public function matchReference(string $referenceText): bool;
public function resolveReference(string $referenceText): ?IReference;
+ public function isGloballyCachable(): bool;
+ public function getCacheKey(string $referenceId): string;
}