Skip to content

Commit

Permalink
Renamed dump command to warmup and invalidate cache if it is unre…
Browse files Browse the repository at this point in the history
…adable
  • Loading branch information
alexandre-daubois committed Feb 22, 2024
1 parent 6091064 commit 0f513f1
Show file tree
Hide file tree
Showing 9 changed files with 43 additions and 20 deletions.
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -208,20 +208,20 @@ name in the PHP class.
## Caching

You can (**and should**) cache the PKL modules to improve performance. This is especially useful when evaluating the same PKL file
multiple times. You can use the `dump` command to dump the PKL module to a cache file. Phikl will then use the cache file automatically when evaluating a PKL file. If the PKL file is not found in the cache, Phikl will evaluate the PKL file on the go.
multiple times. You can use the `warmup` command to dump the PKL modules to a cache file. Phikl will then use the cache file automatically when evaluating a PKL file. If the PKL file is not found in the cache, Phikl will evaluate the PKL file on the go.

**⚠️ Using Phikl with the cache avoids the PKL CLI tool to be executed to evaluate modules and should be done when deploying your application for better performances.**

Phikl will go through all `.pkl` files of your project and dump them to the cache file.

Here's an example of how to use the `dump` command:
Here's an example of how to use the `warmup` command:

```bash
vendor/bin/phikl dump
vendor/bin/phikl warmup

# you can also specify the file if you want to use a custom location
# don't forget to set the `PHIKL_CACHE_FILE` environment variable
vendor/bin/phikl dump --cache-file=cache/pkl.cache
vendor/bin/phikl warmup --cache-file=cache/pkl.cache
```

If you need to validate a cache file, you can do so by using the `validate-cache` command:
Expand All @@ -237,7 +237,7 @@ vendor/bin/phikl validate-cache --cache-file=.cache/.phikl
Here are a few things to note about Phikl cache:

- You can disable the cache by calling `Pkl::toggleCache(false)`, which is useful for development but highly discouraged in production
- Phikl will automatically invalidate the cache if the PKL file is modified or if the cache was generated with a different version of the Pkl CLI tool
- Phikl will automatically refresh the cache if a PKL module is modified since last warmup
- Any corrupted cache entry will be automatically refreshed

If you have your own cache system, you can use the `Pkl::setCache()` method to set the cache system to use. You can pass it any instance of compliant PSR-16 cache system implementing `Psr\SimpleCache\CacheInterface`. This is useful you want to use, for example, a Redis server as a cache system for your Pkl modules.
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
"psr-4": { "Phikl\\": "src", "Phikl\\Tests\\": "tests" }
},
"scripts": {
"test": "./vendor/bin/phpunit",
"test": "./vendor/bin/phpunit --display-warnings",
"cs": "./vendor/bin/php-cs-fixer fix --config=.php-cs-fixer.php --diff --allow-risky=yes",
"stan": "vendor/bin/phpstan analyse src tests -l 8"
},
Expand Down
11 changes: 10 additions & 1 deletion src/Cache/PersistentCache.php
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,16 @@ public function load(): void
return;
}

$this->entries = unserialize($content, ['allowed_classes' => [self::class, Entry::class]]) ?: [];
$unserialized = @unserialize($content, ['allowed_classes' => [self::class, Entry::class]]);
if ($unserialized === false) {
// the cache is unreadable, erase everything
$this->entries = null;
@unlink($cacheFile);

return;
}

$this->entries = $unserialized;
}

/**
Expand Down
2 changes: 1 addition & 1 deletion src/Exception/CorruptedCacheException.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,6 @@ class CorruptedCacheException extends \RuntimeException
{
public function __construct(string $cacheFile)
{
parent::__construct(sprintf('The cache file "%s" seems corrupted and should be generated again with the `phikl dump` command.', $cacheFile));
parent::__construct(sprintf('The cache file "%s" seems corrupted and should be generated again with the `phikl warmup` command.', $cacheFile));
}
}
2 changes: 1 addition & 1 deletion src/Exception/EmptyCacheException.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,6 @@ class EmptyCacheException extends \RuntimeException
{
public function __construct(string $cacheFile)
{
parent::__construct(sprintf('The cache file "%s" is empty or does not exist and should be generated again with the `phikl dump` command.', $cacheFile));
parent::__construct(sprintf('The cache file "%s" is empty or does not exist and should be generated again with the `phikl warmup` command.', $cacheFile));
}
}
12 changes: 6 additions & 6 deletions src/Internal/Command/Runner.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ public static function run(InputInterface $input, OutputInterface $output): int
return self::version($input, $output);
} elseif ($input->getArgument('subcommand') === 'eval') {
return self::eval($input, $output);
} elseif ($input->getArgument('subcommand') === 'dump') {
return self::dump($input, $output);
} elseif ($input->getArgument('subcommand') === 'warmup') {
return self::warmup($input, $output);
} elseif ($input->getArgument('subcommand') === 'validate-cache') {
return self::validateCache($input, $output);
}
Expand Down Expand Up @@ -101,15 +101,15 @@ private static function eval(InputInterface $input, OutputInterface $output): in
return Command::SUCCESS;
}

private static function dump(InputInterface $input, OutputInterface $output): int
private static function warmup(InputInterface $input, OutputInterface $output): int
{
$io = new SymfonyStyle($input, $output);
$cacheFile = $input->getOption('cache-file') ?? self::guessCacheFile();

try {
$count = Pkl::dump($cacheFile);
$count = Pkl::warmup($cacheFile);

$io->success(sprintf('%d files dumped to "%s" cache file.', $count, $cacheFile));
$io->success(sprintf('%d files warmed up to "%s" cache file.', $count, $cacheFile));

if ($cacheFile !== '.phikl.cache') {
$io->caution('Make sure to declare the PHIKL_CACHE_FILE environment variable to use the cache file.');
Expand All @@ -129,7 +129,7 @@ private static function validateCache(InputInterface $input, OutputInterface $ou
$cacheFile = $input->getOption('cache-file') ?? self::guessCacheFile();

if (!file_exists($cacheFile)) {
$io->warning(sprintf('Cache file "%s" does not exist, it can be generated with the `phikl dump` command.', $cacheFile));
$io->warning(sprintf('Cache file "%s" does not exist, it can be generated with the `phikl warmup` command.', $cacheFile));

return Command::FAILURE;
}
Expand Down
4 changes: 2 additions & 2 deletions src/Pkl.php
Original file line number Diff line number Diff line change
Expand Up @@ -151,9 +151,9 @@ public static function rawEval(string ...$modules): string
* The cache file is used to avoid calling the PKL CLI tool on every
* `Pkl::eval()` call.
*
* @return int the number of dumped files
* @return int the number of warmed up files
*/
public static function dump(string $cacheFile): int
public static function warmup(string $cacheFile): int
{
self::initExecutable();

Expand Down
16 changes: 15 additions & 1 deletion tests/Cache/PersistentCacheTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,20 @@ public function testGetCacheFile(): void
$this->assertSame('.phikl.cache', $cache->getCacheFile());
}

public function testLoadWithCorruptedCacheFile(): void
{
$cache = new PersistentCache();
$cache->set('key', new Entry('content', 'hash', 0));
$cache->save();

$cacheFile = $cache->getCacheFile();
file_put_contents($cacheFile, 'invalid');

$cache->load();
$this->assertNull($cache->get('key'));
$this->assertFileDoesNotExist($cacheFile);
}

public function testSetCacheFile(): void
{
$cache = new PersistentCache();
Expand Down Expand Up @@ -260,7 +274,7 @@ public function testValidateOnInvalidCache(): void
$cache->save();

$this->expectException(CorruptedCacheException::class);
$this->expectExceptionMessage('The cache file ".phikl.cache" seems corrupted and should be generated again with the `phikl dump` command.');
$this->expectExceptionMessage('The cache file ".phikl.cache" seems corrupted and should be generated again with the `phikl warmup` command.');

$cache->validate();
}
Expand Down
4 changes: 2 additions & 2 deletions tests/PhiklCommandTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ public function testCanEval(): void

public function testCanDump(): void
{
$process = new Process(['php', __DIR__.'/../phikl', 'dump', 'tests/Fixtures/simple.pkl']);
$process = new Process(['php', __DIR__.'/../phikl', 'warmup', 'tests/Fixtures/simple.pkl']);
$process->mustRun();

$this->assertFileExists('.phikl.cache');
Expand All @@ -61,7 +61,7 @@ public function testCanDump(): void

public function testCanValidateCache(): void
{
$process = new Process(['php', __DIR__.'/../phikl', 'dump', 'tests/Fixtures/simple.pkl']);
$process = new Process(['php', __DIR__.'/../phikl', 'warmup', 'tests/Fixtures/simple.pkl']);
$process->mustRun();

$process = new Process(['php', __DIR__.'/../phikl', 'validate-cache']);
Expand Down

0 comments on commit 0f513f1

Please sign in to comment.