Skip to content
Prev Previous commit
Next Next commit
Implement reference provider based caching
Signed-off-by: Julius Härtl <[email protected]>
  • Loading branch information
juliusknorr committed Aug 31, 2022
commit 31be855522fe68956cb38aaca2a9544c5a75f230
19 changes: 18 additions & 1 deletion lib/private/Collaboration/Reference/FileReferenceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,13 @@ public function __construct(IURLGenerator $urlGenerator, IRootFolder $rootFolder
$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);
Expand All @@ -62,6 +67,10 @@ public function resolveReference(string $referenceText): ?IReference {
* @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);

Expand Down Expand Up @@ -90,4 +99,12 @@ private function fetchReference(Reference $reference) {
'preview-available' => false
]);
}

public function isGloballyCachable(): bool {
return false;
}

public function getCacheKey(string $referenceId): string {
return $this->userId;
}
}
18 changes: 15 additions & 3 deletions lib/private/Collaboration/Reference/LinkReferenceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,16 @@ public function __construct(IClientService $clientService, LoggerInterface $logg
$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;
Expand Down Expand Up @@ -87,4 +91,12 @@ private function fetchReference(Reference $reference) {
$reference->setImageUrl($object->images[0]->url);
}
}

public function isGloballyCachable(): bool {
return true;
}

public function getCacheKey(string $referenceId): string {
return '';
}
}
29 changes: 20 additions & 9 deletions lib/private/Collaboration/Reference/ReferenceManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -54,20 +54,31 @@ public function extractReferences(string $text): array {
}

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 {
Expand Down
3 changes: 3 additions & 0 deletions lib/public/Collaboration/Reference/IReferenceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}