Skip to content

Commit

Permalink
Cache DBFile::exists() and reduce calls to file_exists()
Browse files Browse the repository at this point in the history
  • Loading branch information
emteknetnz committed Apr 12, 2020
1 parent e660e76 commit 2d74eee
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 6 deletions.
2 changes: 1 addition & 1 deletion src/Flysystem/FlysystemAssetStore.php
Original file line number Diff line number Diff line change
Expand Up @@ -321,7 +321,7 @@ private function applyToFileOnFilesystem(callable $callable, ParsedFileID $parse
if ($parsedFileID->getHash()) {
$mainFileID = $strategy->buildFileID($strategy->stripVariant($parsedFileID));

if (!$fs->has($mainFileID)) {
if ($mainFileID !== $fileID && !$fs->has($mainFileID)) {
// The main file doesn't exists ... this is kind of weird.
continue;
}
Expand Down
27 changes: 25 additions & 2 deletions src/Storage/DBFile.php
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,15 @@ class DBFile extends DBComposite implements AssetContainer, Thumbnail
'image/vnd.adobe.photoshop',
);

private const EXISTS_CACHED_UNTESTED = 'EXISTS_CACHED_UNTESTED';
private const EXISTS_CACHED_TRUE = 'EXISTS_CACHED_TRUE';
private const EXISTS_CACHED_FALSE = 'EXISTS_CACHED_FALSE';

/**
* Uses to cache calls to ::exists() for the duration of the request
*/
private $existsCached = self::EXISTS_CACHED_UNTESTED;

/**
* Create a new image manipulation
*
Expand Down Expand Up @@ -359,12 +368,22 @@ public function getVisibility()

public function exists()
{
if ($this->existsCached !== self::EXISTS_CACHED_UNTESTED) {
return $this->existsCached === self::EXISTS_CACHED_TRUE;
}
if (empty($this->Filename)) {
return false;
}
return $this
$exists = $this
->getStore()
->exists($this->Filename, $this->Hash, $this->Variant);
$this->existsCached = $exists ? self::EXISTS_CACHED_TRUE : self::EXISTS_CACHED_FALSE;
return $exists;
}

private function resetExistsCached(): void
{
$this->existsCached = self::EXISTS_CACHED_UNTESTED;
}

public function getFilename()
Expand Down Expand Up @@ -545,7 +564,7 @@ public function deleteFile()
if (!$this->Filename) {
return false;
}

$this->resetExistsCached();
return $this
->getStore()
->delete($this->Filename, $this->Hash);
Expand All @@ -554,6 +573,7 @@ public function deleteFile()
public function publishFile()
{
if ($this->Filename) {
$this->resetExistsCached();
$this
->getStore()
->publish($this->Filename, $this->Hash);
Expand All @@ -563,6 +583,7 @@ public function publishFile()
public function protectFile()
{
if ($this->Filename) {
$this->resetExistsCached();
$this
->getStore()
->protect($this->Filename, $this->Hash);
Expand Down Expand Up @@ -600,6 +621,7 @@ public function renameFile($newName)
if (!$this->Filename) {
return null;
}
$this->resetExistsCached();
$newName = $this
->getStore()
->rename($this->Filename, $this->Hash, $newName);
Expand All @@ -614,6 +636,7 @@ public function copyFile($newName)
if (!$this->Filename) {
return null;
}
$this->resetExistsCached();
return $this
->getStore()
->copy($this->Filename, $this->Hash, $newName);
Expand Down
18 changes: 15 additions & 3 deletions src/Storage/Sha1FileHashingService.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@

namespace SilverStripe\Assets\Storage;

use Exception;
use InvalidArgumentException;
use League\Flysystem\Filesystem;
use League\Flysystem\Util;
use League\Flysystem\FileNotFoundException;
use Psr\SimpleCache\CacheInterface;
use SilverStripe\Core\Config\Configurable;
use SilverStripe\Core\Flushable;
Expand Down Expand Up @@ -189,10 +191,20 @@ private function buildCacheKey($fileID, $fs)
*/
private function getTimestamp($fileID, $fs)
{
$timestamp = '';
$filesystem = $this->getFilesystem($fs);
return $filesystem->has($fileID) ?
$filesystem->getTimestamp($fileID) :
DBDatetime::now()->getTimestamp();
// Using a try/catch block instead of Filesystem::has() because that's already
// called in Filesystem::assertPresent()
try {
// Filesystem::getTimestamp($path) will get a timestamp of the physical file
// if it fails for whatever reason, then it will either
// a) return false, or
// b) throw a FileNotFoundException from Filesystem::assertPresent()
$timestamp = $filesystem->getTimestamp($fileID);
} catch (FileNotFoundException $exception) {
// do nothing
}
return $timestamp ?: DBDatetime::now()->getTimestamp();
}

public function invalidate($fileID, $fs)
Expand Down

0 comments on commit 2d74eee

Please sign in to comment.