Аннулирование кэша в компоненте Symfony 3.1

Я использую компонент кэша Symfony 3.1 для хранения некоторых пользовательских метаданных для моих сущностей. Я хотел бы сделать его недействительным, как только будет внесено изменение в любой файл, связанный с этими метаданными.

Я не нашел способа сказать Symfony или компоненту кэша, в частности, следить за изменениями в определенном наборе файлов, Я что-то упустил?

Ниже кода, который я использую для создания пула элементов кэша:

<?php
class MetadataCacheFactory implements MetadataCacheFactoryInterface
{
const CACHE_NAMESPACE = 'my_namespace';

/** @var string */
protected $cacheDir;

public function __construct(KernelInterface $kernel)
{
$this->cacheDir = $kernel->getCacheDir();
}

/**
* {@inheritdoc}
*/
public function create(): CacheItemPoolInterface
{
return AbstractAdapter::createSystemCache(self::CACHE_NAMESPACE, 0, null, $this->cacheDir);
}
}

И код, использующий это:

<?php
class ExampleMetadataFactory implements MetadataFactoryInterface
{
const CACHE_KEY = 'example_metadata';

[...]

/** @var ExampleMetadata */
protected $metadata;

public function __construct(MetadataCacheFactoryInterface $cacheFactory)
{
$this->cache = $cacheFactory->create();
$this->metadata = null;
}

/**
* {@inheritdoc}
*/
public function create(): ExampleMetadata
{
if ($this->metadata !== null) {
return $this->metadata;
}
try {
$cacheItem = $this->cache->getItem(md5(self::CACHE_KEY));
if ($cacheItem->isHit()) {
return $cacheItem->get();
}
} catch (CacheException $e) {
// Ignore
}
$this->metadata = $this->createMetadata();
if (!isset($cacheItem)) {
return $this->metadata;
}
$cacheItem->set($this->metadata);
$this->cache->save($cacheItem);
return $this->metadata;
}
}

Когда я смотрю на код во время выполнения, AbstractAdapter выбрать, чтобы дать мне PhpFilesAdapter (достаточно честно в dev, я думаю).

Но когда я смотрю в код этого адаптера, я нахожу это:

<?php
protected function doFetch(array $ids) {
[...]

foreach ($ids as $id) {
try {
$file = $this->getFile($id);
list($expiresAt, $values[$id]) = include $file;
if ($now >= $expiresAt) {
unset($values[$id]);
}
} catch (\Exception $e) {
continue;
}
}
}

Таким образом, нет никакой логики для проверки истечения срока действия, кроме даты истечения срока действия.

Знаете ли вы способ аннулировать кэш при изменении файла (в среде разработчика, конечно)? Или мне самому это реализовать ..?

Спасибо за вашу помощь.

0

Решение

Я нашел решение: ConfigCache. Вы можете дать ему массив ресурсов для просмотра, и он будет проверять время их последнего изменения при каждом чтении кэша.

Пример выше становится примерно таким:

<?php
class MetadataCacheFactory implements MetadataCacheFactoryInterface
{
const CACHE_NAMESPACE = 'my_namespace';

/** @var \Symfony\Component\HttpKernel\KernelInterface */
protected $kernel;

public function __construct(KernelInterface $kernel)
{
$this->kernel = $kernel;
}

/**
* {@inheritdoc}
*/
public function create(): ConfigCache
{
return new ConfigCache($this->kernel->getCacheDir().'/'.self::CACHE_NAMESPACE, $this->kernel->isDebug());
}
}

И код, использующий это:

<?php
class ExampleMetadataFactory implements MetadataFactoryInterface
{
const CACHE_KEY = 'example_metadata';

[...]

/** @var ExampleMetadata */
protected $metadata;

public function __construct(MetadataCacheFactoryInterface $cacheFactory)
{
$this->cache = $cacheFactory->create();
$this->metadata = null;
}

/**
* {@inheritdoc}
*/
public function create(): ExampleMetadata
{
if ($this->metadata !== null) {
return $this->metadata;
}
try {
if ($this->cache->isFresh()) {
$this->metadata = unserialize(file_get_contents($this->cache->getPath()));
return $this->metadata;
}
} catch (CacheException $e) {
// Ignore
}
$resources = [];
$this->metadata = $this->createMetadata($resources);
$this->cache->write(serialize($this->metadata), $resources);
return $this->metadata;
}

/**
* Creates the metadata.
*
* @param array $resources
*
* @return ExampleMetadata
*/
protected function createMetadata(&$resources): ExampleMetadata
{
$metadata = new ExampleMetadata();
$resourcesCollection = $this->resourcesCollectionFactory->create();
foreach ($resourcesCollection as $resourceClass => $resourcePath) {
// The important part, it's an instance of \Symfony\Component\Config\Resource\FileResource.
$resources[] = new FileResource($resourcePath);
$resourceMetadata = $this->resourceMetadataFactory->create($resourceClass);
$metadata->registerResourceMetadata($resourceMetadata);
}
return $metadata;
}
}

В надежде это может помочь кому-то еще.

1

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector