1
0

Improved performances

This commit is contained in:
Richard Dern 2024-04-24 00:47:46 +02:00
parent acb0a153f3
commit 7e53a39638
3 changed files with 59 additions and 35 deletions

View File

@ -7,9 +7,10 @@
use App\Classes\Traits\ManagesMetadata; use App\Classes\Traits\ManagesMetadata;
use App\Contracts\Bundles; use App\Contracts\Bundles;
use App\Services\BundleRenderers\Facades\BundleRenderer; use App\Services\BundleRenderers\Facades\BundleRenderer;
use Carbon\Carbon;
use Exception; use Exception;
use Illuminate\Filesystem\FilesystemAdapter; use Illuminate\Filesystem\FilesystemAdapter;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Str; use Illuminate\Support\Str;
use League\Flysystem\StorageAttributes; use League\Flysystem\StorageAttributes;
@ -23,6 +24,10 @@ class Bundle implements Bundles
protected int $currentPage = 1; protected int $currentPage = 1;
protected ?Bundle $section;
protected ?Bundle $parent;
public function __construct(protected string $path, protected FilesystemAdapter $disk) public function __construct(protected string $path, protected FilesystemAdapter $disk)
{ {
$this->path = $this->normalizeBundlePath($path); $this->path = $this->normalizeBundlePath($path);
@ -68,13 +73,35 @@ public function getDisk(): FilesystemAdapter
*/ */
public function getSection(): ?Bundle 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) { if (count($parts) > 0) {
return new Bundle($parts[0], $this->disk); $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->saveAttachments();
$this->saveMetadata(); $this->saveMetadata();
$this->saveMarkdown(); $this->saveMarkdown();
$this->touchCache();
} }
/** /**
@ -154,14 +182,16 @@ public function renderCard()
*/ */
public static function findBundles(FilesystemAdapter $disk, ?string $path = '/', bool $recursive = false): array public static function findBundles(FilesystemAdapter $disk, ?string $path = '/', bool $recursive = false): array
{ {
$start = microtime(true);
$bundles = [];
if ($recursive) { if ($recursive) {
return $disk $bundles = $disk
->listContents($path, $recursive) ->listContents($path, $recursive)
->filter(fn (StorageAttributes $attributes) => ($attributes->isFile() && Str::endsWith($attributes->path(), '.md'))) ->filter(fn (StorageAttributes $attributes) => ($attributes->isFile() && Str::endsWith($attributes->path(), '.md')))
->map(fn (StorageAttributes $attributes) => new Bundle(dirname($attributes->path()), $disk)) ->map(fn (StorageAttributes $attributes) => new Bundle(dirname($attributes->path()), $disk))
->toArray(); ->toArray();
} else { } else {
$bundles = [];
$directories = $disk->directories($path); $directories = $disk->directories($path);
foreach ($directories as $directory) { foreach ($directories as $directory) {
@ -171,31 +201,26 @@ public static function findBundles(FilesystemAdapter $disk, ?string $path = '/',
$bundles[] = $bundle; $bundles[] = $bundle;
} }
} }
return $bundles;
} }
$finish = microtime(true);
$diff = $finish - $start;
Log::debug('findBundles', [
'path' => $path,
'duration' => $diff,
]);
return $bundles;
} }
/** public function touchCache()
* Return the most recent modification date of this bundle and all
* sub-bundles
*/
public function lastModified(): ?Carbon
{ {
$dates = $this->disk $cacheKey = sprintf('lastModified_%s', Str::slug($this->getPath()));
->listContents($this->getPath(), true)
->map(fn (StorageAttributes $attributes) => $attributes->lastModified())
->toArray();
$latestTime = 0; Cache::put($cacheKey, now());
foreach ($dates as $date) { optional($this->getParent())->touchCache();
if ($date > $latestTime) {
$latestTime = $date;
}
}
return $latestTime == 0 ? null : Carbon::parse($latestTime);
} }
private function repairCover() private function repairCover()

View File

@ -8,6 +8,7 @@
use Carbon\Carbon; use Carbon\Carbon;
use Exception; use Exception;
use Illuminate\Support\Facades\Cache; use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Str;
abstract class BaseRenderer implements RendersBundle abstract class BaseRenderer implements RendersBundle
{ {
@ -100,23 +101,21 @@ protected function handlePagination()
{ {
$itemsPerPage = config('pagination.itemsPerPage'); $itemsPerPage = config('pagination.itemsPerPage');
$currentPage = $this->bundle->getCurrentPage(); $currentPage = $this->bundle->getCurrentPage();
$lastModified = $this->bundle->lastModified(); $cacheName = Str::slug($this->bundle->getPath());
$cacheKey = sprintf('subBundles_%s', $cacheName);
$cacheKey = sprintf('subBundles_%s', base64_encode($this->bundle->getPath())); $cacheKeyLm = sprintf('lastModified_%s', $cacheName);
$cacheKeyLm = sprintf('subBundles_%s_lastModified', base64_encode($this->bundle->getPath()));
if ( if (
Cache::has($cacheKeyLm) Cache::has($cacheKeyLm)
&& Cache::has($cacheKey) && Cache::has($cacheKey)
&& $lastModified
&& Cache::get($cacheKeyLm)->gte($lastModified)
) { ) {
$subBundles = Cache::get($cacheKey); $subBundles = Cache::get($cacheKey);
} else { } else {
$subBundles = $this->collectSubBundles(); $subBundles = $this->collectSubBundles();
Cache::put($cacheKey, $subBundles, now()->addWeek()); Cache::put($cacheKey, $subBundles, now()->addWeek());
Cache::put($cacheKeyLm, $lastModified, now()->addWeek());
$this->bundle->touchCache();
} }
if (!$this->bundle->exists() && empty($subBundles)) { if (!$this->bundle->exists() && empty($subBundles)) {

View File

@ -51,7 +51,7 @@ public function render(): string
$cacheKey = sprintf('markdown_formatted_%s', $hash); $cacheKey = sprintf('markdown_formatted_%s', $hash);
if (Cache::has($cacheKey)) { if (Cache::has($cacheKey)) {
// return Cache::get($cacheKey); return Cache::get($cacheKey);
} }
// First, process the source with Blade to handle any dynamic content // 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->insertNonBreakingSpaces($converted->getContent());
$result = $this->removeEmptyCodeLines($result); $result = $this->removeEmptyCodeLines($result);
// Cache::put($cacheKey, $result, now()->addMonth()); Cache::put($cacheKey, $result, now()->addMonth());
return $result; return $result;
} }