allow vendord
All checks were successful
Build, Push and Deploy / build-and-push (push) Successful in 3m3s
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 16s
Build, Push and Deploy / deploy-staging (push) Successful in 32s
Build, Push and Deploy / deploy-production (push) Has been skipped
Build, Push and Deploy / cleanup (push) Successful in 1s
All checks were successful
Build, Push and Deploy / build-and-push (push) Successful in 3m3s
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 16s
Build, Push and Deploy / deploy-staging (push) Successful in 32s
Build, Push and Deploy / deploy-production (push) Has been skipped
Build, Push and Deploy / cleanup (push) Successful in 1s
This commit is contained in:
90
vendor/cuyz/valinor/src/Cache/FileWatchingCache.php
vendored
Normal file
90
vendor/cuyz/valinor/src/Cache/FileWatchingCache.php
vendored
Normal file
@@ -0,0 +1,90 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace CuyZ\Valinor\Cache;
|
||||
|
||||
use function file_exists;
|
||||
use function filemtime;
|
||||
use function var_export;
|
||||
|
||||
/**
|
||||
* This cache implementation will watch the files of the application and
|
||||
* invalidate cache entries when a PHP file is modified — preventing the library
|
||||
* not behaving as expected when the signature of a property or a method
|
||||
* changes.
|
||||
*
|
||||
* This is especially useful when the application runs in a development
|
||||
* environment, where source files are often modified by developers.
|
||||
*
|
||||
* It should decorate the original cache implementation and should be given to
|
||||
* the mapper builder: @see \CuyZ\Valinor\MapperBuilder::withCache
|
||||
*
|
||||
* @api
|
||||
*
|
||||
* @template EntryType
|
||||
* @implements Cache<EntryType>
|
||||
*/
|
||||
final class FileWatchingCache implements Cache
|
||||
{
|
||||
/** @var array<string, array<string, int>> */
|
||||
private array $timestamps = [];
|
||||
|
||||
public function __construct(
|
||||
/** @var Cache<EntryType> */
|
||||
private Cache $delegate,
|
||||
) {}
|
||||
|
||||
/** @internal */
|
||||
public function get(string $key, mixed ...$arguments): mixed
|
||||
{
|
||||
$this->timestamps[$key] ??= $this->delegate->get("$key.timestamps"); // @phpstan-ignore assign.propertyType
|
||||
|
||||
if ($this->timestamps[$key] === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
assert(is_array($this->timestamps[$key]));
|
||||
|
||||
foreach ($this->timestamps[$key] as $fileName => $timestamp) {
|
||||
if (! file_exists($fileName)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (filemtime($fileName) !== $timestamp) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
return $this->delegate->get($key, ...$arguments);
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
public function set(string $key, CacheEntry $entry): void
|
||||
{
|
||||
$this->delegate->set($key, $entry);
|
||||
|
||||
$this->timestamps[$key] = [];
|
||||
|
||||
foreach ($entry->filesToWatch as $fileName) {
|
||||
$time = @filemtime($fileName);
|
||||
|
||||
if (false === $time) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->timestamps[$key][$fileName] = $time;
|
||||
}
|
||||
|
||||
$code = 'fn () => ' . var_export($this->timestamps[$key], true);
|
||||
|
||||
$this->delegate->set("$key.timestamps", new CacheEntry($code));
|
||||
}
|
||||
|
||||
public function clear(): void
|
||||
{
|
||||
$this->timestamps = [];
|
||||
|
||||
$this->delegate->clear();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user