Skip to content

Commit

Permalink
Build reproductible TemplateMap
Browse files Browse the repository at this point in the history
  • Loading branch information
smnandre authored and weaverryan committed Feb 16, 2024
1 parent 30c8dbc commit 5849a6c
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,11 @@ function (ChildDefinition $definition, AsLiveComponent $attribute) {
->setArguments(['%kernel.cache_dir%/'.self::TEMPLATES_MAP_FILENAME]);

$container->register('ux.live_component.twig.cache_warmer', TemplateCacheWarmer::class)
->setArguments([new Reference('twig.template_iterator'), self::TEMPLATES_MAP_FILENAME])
->setArguments([
new Reference('twig.template_iterator'),
self::TEMPLATES_MAP_FILENAME,
'%kernel.secret%',
])
->addTag('kernel.cache_warmer');
}

Expand Down
9 changes: 6 additions & 3 deletions src/LiveComponent/src/Twig/TemplateCacheWarmer.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,18 @@
*/
final class TemplateCacheWarmer implements CacheWarmerInterface
{
public function __construct(private \IteratorAggregate $templateIterator, private readonly string $cacheFilename)
{
public function __construct(
private readonly \IteratorAggregate $templateIterator,
private readonly string $cacheFilename,
private readonly string $secret,
) {
}

public function warmUp(string $cacheDir, ?string $buildDir = null): array
{
$map = [];
foreach ($this->templateIterator as $item) {
$map[bin2hex(random_bytes(16))] = $item;
$map[hash('xxh128', $item.$this->secret)] = $item;
}

(new PhpArrayAdapter($cacheDir.'/'.$this->cacheFilename, new NullAdapter()))->warmUp(['map' => $map]);
Expand Down
2 changes: 1 addition & 1 deletion src/LiveComponent/src/Twig/TemplateMap.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public function __construct(string $cacheFile)
$this->map = (new PhpArrayAdapter($cacheFile, new NullAdapter()))->getItem('map')->get();
}

public function resolve(string $obscuredName)
public function resolve(string $obscuredName): string
{
return $this->map[$obscuredName] ?? throw new \RuntimeException(sprintf('Cannot find a template matching "%s". Cache may be corrupt.', $obscuredName));
}
Expand Down
78 changes: 78 additions & 0 deletions src/LiveComponent/tests/Unit/Twig/TemplateCacheWarmerTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
<?php

/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Symfony\UX\LiveComponent\Tests\Unit\Twig;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Cache\Adapter\NullAdapter;
use Symfony\Component\Cache\Adapter\PhpArrayAdapter;
use Symfony\UX\LiveComponent\Twig\TemplateCacheWarmer;

/**
* @author Simon André <smn.andre@gmail.com>
*/
final class TemplateCacheWarmerTest extends TestCase
{
private string $cacheDir;
private string $cacheFile;
private TemplateCacheWarmer $templateCacheWarmer;

protected function setUp(): void
{
$this->cacheDir ??= sys_get_temp_dir();
$this->cacheFile ??= $this->cacheDir.'/cache_file';
if (file_exists($this->cacheFile)) {
unlink($this->cacheFile);
}
$this->templateCacheWarmer ??= new TemplateCacheWarmer(
new \ArrayObject(['template1', 'template2']),
'cache_file',
'secret'
);
}

public function testWarmUpCreatesCacheFile(): void
{
$this->assertFileDoesNotExist($this->cacheFile);

$this->templateCacheWarmer->warmUp($this->cacheDir);

$this->assertFileExists($this->cacheFile);
}

public function testWarmUpCreatesCorrectCacheContent(): void
{
$this->templateCacheWarmer->warmUp($this->cacheDir);
$adapter = new PhpArrayAdapter($this->cacheFile, new NullAdapter());
$item = $adapter->getItem('map');

$this->assertSame(
[
hash('xxh128', 'template1secret') => 'template1',
hash('xxh128', 'template2secret') => 'template2',
],
$item->get()
);
}

public function testWarmUpCreatesReproductibleTemplateMap(): void
{
$this->templateCacheWarmer->warmUp($this->cacheDir);
$adapter = new PhpArrayAdapter($this->cacheFile, new NullAdapter());
$map1 = $adapter->getItem('map')->get();

$this->templateCacheWarmer->warmUp($this->cacheDir);
$adapter = new PhpArrayAdapter($this->cacheFile, new NullAdapter());
$map2 = $adapter->getItem('map')->get();

$this->assertSame($map1, $map2);
}
}

0 comments on commit 5849a6c

Please sign in to comment.