Skip to content

Commit

Permalink
[4.x] Improve collection Stache watcher performance (#9302)
Browse files Browse the repository at this point in the history
  • Loading branch information
JohnathonKoster authored Jan 30, 2024
1 parent 2d58efb commit a18568a
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 4 deletions.
2 changes: 2 additions & 0 deletions src/Stache/Stores/CollectionsStore.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@

class CollectionsStore extends BasicStore
{
protected $traverseRecursively = false;

public function key()
{
return 'collections';
Expand Down
5 changes: 3 additions & 2 deletions src/Stache/Stores/Store.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ abstract class Store
protected $storeIndexes = [];
protected $usedIndexes;
protected $fileChangesHandled = false;
protected $traverseRecursively = true;
protected $paths;
protected $fileItems;
protected $shouldCacheFileItems = false;
Expand Down Expand Up @@ -180,7 +181,7 @@ public function handleFileChanges()
$existing = collect(Cache::get($cacheKey, []));

// Get the files and timestamps from the filesystem right now.
$files = Traverser::filter([$this, 'getItemFilter'])->traverse($this);
$files = Traverser::filter([$this, 'getItemFilter'])->traverse($this, $this->traverseRecursively);

// Cache the files and timestamps, ready for comparisons on the next request.
// We'll do it now since there are multiple early returns coming up.
Expand Down Expand Up @@ -292,7 +293,7 @@ public function paths()
return $this->paths = collect($paths);
}

$files = Traverser::filter([$this, 'getItemFilter'])->traverse($this);
$files = Traverser::filter([$this, 'getItemFilter'])->traverse($this, $this->traverseRecursively);

$fileItems = $files->map(function ($timestamp, $path) {
return [
Expand Down
33 changes: 31 additions & 2 deletions src/Stache/Traverser.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,13 @@

namespace Statamic\Stache;

use DirectoryIterator;
use FilesystemIterator;
use Illuminate\Filesystem\Filesystem;
use RecursiveDirectoryIterator;
use RecursiveIteratorIterator;
use Statamic\Facades\Path;
use Symfony\Component\Finder\SplFileInfo;

class Traverser
{
Expand All @@ -15,7 +20,7 @@ public function __construct(Filesystem $filesystem)
$this->filesystem = $filesystem;
}

public function traverse($store)
public function traverse($store, $recursive = true)
{
if (! $dir = $store->directory()) {
throw new \Exception("Store [{$store->key()}] does not have a directory defined.");
Expand All @@ -27,7 +32,7 @@ public function traverse($store)
return collect();
}

$files = collect($this->filesystem->allFiles($dir));
$files = collect($this->getFiles($dir, $recursive));

if ($this->filter) {
$files = $files->filter($this->filter);
Expand All @@ -45,4 +50,28 @@ public function filter($filter)

return $this;
}

private function getFiles($dir, $recursive)
{
$files = [];

if ($recursive) {
$iterator = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator($dir, FilesystemIterator::SKIP_DOTS | FilesystemIterator::CURRENT_AS_SELF),
RecursiveIteratorIterator::CHILD_FIRST
);
} else {
$iterator = new DirectoryIterator($dir);
}

foreach ($iterator as $fileInfo) {
if ($fileInfo->isDir() || $fileInfo->getFilename()[0] === '.') {
continue;
}

$files[] = new SplFileInfo($fileInfo->getPathname(), $fileInfo->getPath(), $fileInfo->getFilename());
}

return $files;
}
}

0 comments on commit a18568a

Please sign in to comment.