Add cache only MappingDriver implementation and use in prod. mode
We used to rely on Doctrine never calling MappingDriver when metadata are cached. But we learned that there are some cases where Doctrine uses the driver. In this commit we add custom MappingDriver that works on top of metadata cache. [MAILPOET-4218]
This commit is contained in:
committed by
Veljko V
parent
d41e395a74
commit
8afab5105f
55
mailpoet/lib/Doctrine/CacheOnlyMappingDriver.php
Normal file
55
mailpoet/lib/Doctrine/CacheOnlyMappingDriver.php
Normal file
@ -0,0 +1,55 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
namespace MailPoet\Doctrine;
|
||||
|
||||
use MailPoet\RuntimeException;
|
||||
use MailPoetVendor\Doctrine\Persistence\Mapping\ClassMetadata;
|
||||
use MailPoetVendor\Doctrine\Persistence\Mapping\Driver\MappingDriver;
|
||||
use MailPoetVendor\Psr\Cache\CacheItemPoolInterface;
|
||||
|
||||
/**
|
||||
* Intended to be used in production environment where we rely on metadata cache for reading all metadata.
|
||||
*/
|
||||
class CacheOnlyMappingDriver implements MappingDriver {
|
||||
/** @var string */
|
||||
protected $cacheSalt = '__CLASSMETADATA__';
|
||||
|
||||
/** @var CacheItemPoolInterface */
|
||||
private $metaDataCache;
|
||||
|
||||
public function __construct(
|
||||
CacheItemPoolInterface $metaDataCache
|
||||
) {
|
||||
$this->metaDataCache = $metaDataCache;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inerhitDoc
|
||||
*/
|
||||
public function loadMetadataForClass($className, ClassMetadata $metadata) {
|
||||
// We don't need to load anything it is all cached.
|
||||
}
|
||||
|
||||
/**
|
||||
* @inerhitDoc
|
||||
*/
|
||||
public function getAllClassNames() {
|
||||
throw new RuntimeException('CacheOnlyMappingDriver::getAllClassNames should not be called');
|
||||
}
|
||||
|
||||
/**
|
||||
* @inerhitDoc
|
||||
*/
|
||||
public function isTransient($className) {
|
||||
// Everything in cache are metadata and class with metadata is non-transient
|
||||
// See https://github.com/doctrine/persistence/blob/b07e347a24e7a19a2b6462e00a6dff899e4c2dd2/src/Persistence/Mapping/Driver/MappingDriver.php#L34
|
||||
return !$this->metaDataCache->hasItem($this->getCacheKey($className));
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy pasted from MailPoetVendor\Doctrine\Persistence\Mapping\AbstractClassMetadataFactory
|
||||
*/
|
||||
protected function getCacheKey(string $className) : string {
|
||||
return str_replace('\\', '__', $className) . $this->cacheSalt;
|
||||
}
|
||||
}
|
@ -6,7 +6,6 @@ use MailPoet\Doctrine\Annotations\AnnotationReaderProvider;
|
||||
use MailPoetVendor\Doctrine\Common\Proxy\AbstractProxyFactory;
|
||||
use MailPoetVendor\Doctrine\ORM\Configuration;
|
||||
use MailPoetVendor\Doctrine\ORM\Mapping\Driver\AnnotationDriver;
|
||||
use MailPoetVendor\Doctrine\Persistence\Mapping\Driver\PHPDriver;
|
||||
use MailPoetVendor\Doctrine\ORM\Mapping\UnderscoreNamingStrategy;
|
||||
|
||||
class ConfigurationFactory {
|
||||
@ -41,17 +40,15 @@ class ConfigurationFactory {
|
||||
|
||||
// annotation reader exists only in dev environment, on production cache is pre-generated
|
||||
$annotationReader = $this->annotationReaderProvider->getAnnotationReader();
|
||||
if ($annotationReader) {
|
||||
$configuration->setMetadataDriverImpl(new AnnotationDriver($annotationReader, [self::ENTITY_DIR]));
|
||||
} else {
|
||||
// Should never be called but Doctrine requires having driver set
|
||||
$configuration->setMetadataDriverImpl(new PHPDriver([]));
|
||||
}
|
||||
|
||||
// metadata cache (for production cache is pre-generated at build time)
|
||||
$isReadOnly = !$annotationReader;
|
||||
$metadataStorage = new PSRMetadataCache(self::METADATA_DIR, $isReadOnly);
|
||||
$configuration->setMetadataCache($metadataStorage);
|
||||
|
||||
if ($isReadOnly) {
|
||||
$configuration->setMetadataDriverImpl(new CacheOnlyMappingDriver($metadataStorage));
|
||||
} else {
|
||||
$configuration->setMetadataDriverImpl(new AnnotationDriver($annotationReader, [self::ENTITY_DIR]));
|
||||
}
|
||||
}
|
||||
|
||||
private function configureProxies(Configuration $configuration) {
|
||||
|
Reference in New Issue
Block a user