From 7e53a39638925e314ec2af85bba0c8b8c96e9d16 Mon Sep 17 00:00:00 2001 From: Richard Dern Date: Wed, 24 Apr 2024 00:47:46 +0200 Subject: [PATCH] Improved performances --- app/Classes/Bundle.php | 77 ++++++++++++------- .../Renderers/BaseRenderer.php | 13 ++-- app/Services/Markdown/Formatter.php | 4 +- 3 files changed, 59 insertions(+), 35 deletions(-) diff --git a/app/Classes/Bundle.php b/app/Classes/Bundle.php index ff72ef2..d852547 100644 --- a/app/Classes/Bundle.php +++ b/app/Classes/Bundle.php @@ -7,9 +7,10 @@ use App\Classes\Traits\ManagesMetadata; use App\Contracts\Bundles; use App\Services\BundleRenderers\Facades\BundleRenderer; -use Carbon\Carbon; use Exception; use Illuminate\Filesystem\FilesystemAdapter; +use Illuminate\Support\Facades\Cache; +use Illuminate\Support\Facades\Log; use Illuminate\Support\Str; use League\Flysystem\StorageAttributes; @@ -23,6 +24,10 @@ class Bundle implements Bundles protected int $currentPage = 1; + protected ?Bundle $section; + + protected ?Bundle $parent; + public function __construct(protected string $path, protected FilesystemAdapter $disk) { $this->path = $this->normalizeBundlePath($path); @@ -68,13 +73,35 @@ public function getDisk(): FilesystemAdapter */ public function getSection(): ?Bundle { - $parts = preg_split('#/#', $this->path, -1, PREG_SPLIT_NO_EMPTY); + if (!isset($this->section)) { + $parts = preg_split('#/#', $this->path, -1, PREG_SPLIT_NO_EMPTY); - if (count($parts) > 0) { - return new Bundle($parts[0], $this->disk); + if (count($parts) > 0) { + $this->section = new Bundle($parts[0], $this->disk); + } else { + $this->section = null; + } } - return null; + return $this->section; + } + + /** + * Return the parent bundle where this bundle is located + */ + public function getParent(): ?Bundle + { + if (!isset($this->parent)) { + $parts = preg_split('#/#', $this->path, -1, PREG_SPLIT_NO_EMPTY); + + if (count($parts) > 0) { + $this->parent = new Bundle($parts[count($parts) - 1], $this->disk); + } else { + $this->parent = null; + } + } + + return $this->parent; } /** @@ -104,6 +131,7 @@ public function save(): void $this->saveAttachments(); $this->saveMetadata(); $this->saveMarkdown(); + $this->touchCache(); } /** @@ -154,14 +182,16 @@ public function renderCard() */ public static function findBundles(FilesystemAdapter $disk, ?string $path = '/', bool $recursive = false): array { + $start = microtime(true); + $bundles = []; + if ($recursive) { - return $disk + $bundles = $disk ->listContents($path, $recursive) ->filter(fn (StorageAttributes $attributes) => ($attributes->isFile() && Str::endsWith($attributes->path(), '.md'))) ->map(fn (StorageAttributes $attributes) => new Bundle(dirname($attributes->path()), $disk)) ->toArray(); } else { - $bundles = []; $directories = $disk->directories($path); foreach ($directories as $directory) { @@ -171,31 +201,26 @@ public static function findBundles(FilesystemAdapter $disk, ?string $path = '/', $bundles[] = $bundle; } } - - return $bundles; } + + $finish = microtime(true); + $diff = $finish - $start; + + Log::debug('findBundles', [ + 'path' => $path, + 'duration' => $diff, + ]); + + return $bundles; } - /** - * Return the most recent modification date of this bundle and all - * sub-bundles - */ - public function lastModified(): ?Carbon + public function touchCache() { - $dates = $this->disk - ->listContents($this->getPath(), true) - ->map(fn (StorageAttributes $attributes) => $attributes->lastModified()) - ->toArray(); + $cacheKey = sprintf('lastModified_%s', Str::slug($this->getPath())); - $latestTime = 0; + Cache::put($cacheKey, now()); - foreach ($dates as $date) { - if ($date > $latestTime) { - $latestTime = $date; - } - } - - return $latestTime == 0 ? null : Carbon::parse($latestTime); + optional($this->getParent())->touchCache(); } private function repairCover() diff --git a/app/Services/BundleRenderers/Renderers/BaseRenderer.php b/app/Services/BundleRenderers/Renderers/BaseRenderer.php index f0e09b5..fc3cc2d 100644 --- a/app/Services/BundleRenderers/Renderers/BaseRenderer.php +++ b/app/Services/BundleRenderers/Renderers/BaseRenderer.php @@ -8,6 +8,7 @@ use Carbon\Carbon; use Exception; use Illuminate\Support\Facades\Cache; +use Illuminate\Support\Str; abstract class BaseRenderer implements RendersBundle { @@ -100,23 +101,21 @@ protected function handlePagination() { $itemsPerPage = config('pagination.itemsPerPage'); $currentPage = $this->bundle->getCurrentPage(); - $lastModified = $this->bundle->lastModified(); - - $cacheKey = sprintf('subBundles_%s', base64_encode($this->bundle->getPath())); - $cacheKeyLm = sprintf('subBundles_%s_lastModified', base64_encode($this->bundle->getPath())); + $cacheName = Str::slug($this->bundle->getPath()); + $cacheKey = sprintf('subBundles_%s', $cacheName); + $cacheKeyLm = sprintf('lastModified_%s', $cacheName); if ( Cache::has($cacheKeyLm) && Cache::has($cacheKey) - && $lastModified - && Cache::get($cacheKeyLm)->gte($lastModified) ) { $subBundles = Cache::get($cacheKey); } else { $subBundles = $this->collectSubBundles(); Cache::put($cacheKey, $subBundles, now()->addWeek()); - Cache::put($cacheKeyLm, $lastModified, now()->addWeek()); + + $this->bundle->touchCache(); } if (!$this->bundle->exists() && empty($subBundles)) { diff --git a/app/Services/Markdown/Formatter.php b/app/Services/Markdown/Formatter.php index 415da41..375a09f 100644 --- a/app/Services/Markdown/Formatter.php +++ b/app/Services/Markdown/Formatter.php @@ -51,7 +51,7 @@ public function render(): string $cacheKey = sprintf('markdown_formatted_%s', $hash); if (Cache::has($cacheKey)) { - // return Cache::get($cacheKey); + return Cache::get($cacheKey); } // First, process the source with Blade to handle any dynamic content @@ -65,7 +65,7 @@ public function render(): string $result = $this->insertNonBreakingSpaces($converted->getContent()); $result = $this->removeEmptyCodeLines($result); - // Cache::put($cacheKey, $result, now()->addMonth()); + Cache::put($cacheKey, $result, now()->addMonth()); return $result; }