-
-
Notifications
You must be signed in to change notification settings - Fork 455
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add PhpArrayAdapter to cache metadata #1196
Conversation
That can be changed, PR welcome on symfony/symfony to discuss it there.
This would be better implemented on the bundle imho, as that would allow releasing the logic in sync with the feature provided here. |
…ic (ossinkine) This PR was submitted for the 3.4 branch but it was merged into the 5.2-dev branch instead. Discussion ---------- [FrameworkBundle] Make AbstractPhpFileCacheWarmer public | Q | A | ------------- | --- | Branch? | 3.4 | Bug fix? | no | New feature? | no | Deprecations? | no | License | MIT Introducing the PhpArrayAdapter was a great feature. It has proven itself well in the production. Actually, using the adapter is closely related to warming up the cache for it. FrameworkBundle has an AbstractPhpFileCacheWarmer for conveniently creating a custom warmer. But using it outside of the FrameworkBundle becomes more complicated because it is marked as internal. I propose making it public and allow it to be used outside of the FrameworkBundle. For example, I've proposed to cache Doctrine metadata using PhpArrayAdapter and the implementation uses AbstractPhpFileCacheWarmer doctrine/DoctrineBundle#1196 Commits ------- a0fb442 Make AbstractPhpFileCacheWarmer public
$cacheWarmerDefinition->addTag('kernel.cache_warmer'); | ||
} | ||
|
||
private function registerMetadataPhpArrayCache(string $entityManagerName, ContainerBuilder $container): void |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would personally prefer to not unnecessarily register new service if its only purpose is to inject it to warmer. Service should be instead just inlined, IMHO. Otherwise we are unnecessarily increasing public API surface.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
doctrine.orm.default_metadata_cache
is the alias which refers to the cache service. How can I create inline service and refer the alias to it?
/** | ||
* Removes redundant decorators such DoctrineAdapter -> DoctrineProvider -> AdapterInterface. | ||
*/ | ||
class PhpArrayCachePass implements CompilerPassInterface |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We would prefer not having to maintain this in bundle forever. Can you please contribute this to Symfony core too? That way you will also get better feedback, as I'm not exactly confident about these internals.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As I understand @nicolas-grekas has another opinion. Since this is just optimization we can merge without it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nicolas didn't mean it doesn't make sense to contribute to Symfony, he said it needs to be merged to doctrine bundle anyways, as otherwise this feature would be available in next minor Symfony version only. But yeah I am also ok with just removing it for now, would make it easier to merge
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tests are DI only, very simplistic. Can we have test which asserts that cache is hit when loading metadata and not generated again? Also, can you provide some numbers so everyone can see what's the expected improvement?
Also, we probably need to mark a test as legacy so CI passes.
And of course, needs to be rebased as it has conflicts.
b66fa48
to
66a7930
Compare
Tests don't passed because AbstractPhpFileCacheWarmer marked as internal, |
Hmm, I didn't consider this aspect. |
… (ossinkine) This PR was merged into the 3.4 branch. Discussion ---------- [FrameworkBundle] Make AbstractPhpFileCacheWarmer public | Q | A | ------------- | --- | Branch? | 3.4 | Bug fix? | no | New feature? | no | Deprecations? | no | License | MIT The same as #37951 but with 3.4 as base branch, see doctrine/DoctrineBundle#1196 (comment) cc @nicolas-grekas Commits ------- b82d9a2 Make AbstractPhpFileCacheWarmer public
Any chance for finishing this @ossinkine? |
@ostrolucky I can remove |
Sounds good enough to me! |
092c8dc
to
7d2d76d
Compare
@ostrolucky I've removed the commit with optimizations, rebased the branch from the master and fixed code style issue except the one, I think proposed fix is a bad idea |
c88e9d2
to
bb74383
Compare
7b28e7e
to
c925eed
Compare
How about this. Does that work for you @ossinkine? |
c925eed
to
58f56fe
Compare
this could actually be simple. We can add a tag on the services and use that tag in the compiler pass |
58f56fe
to
f1a5aca
Compare
@@ -688,6 +688,13 @@ private function getOrmCacheDriverNode(string $name): ArrayNodeDefinition | |||
->scalarNode('pool')->end() | |||
->end(); | |||
|
|||
if ($name === 'metadata_cache_driver') { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this means we also need to create a new recipe for 2.2?
See https://github.com/symfony/recipes/blob/master/doctrine/doctrine-bundle/1.12/config/packages/prod/doctrine.yaml#L4 (it's used for 2.x currently as well via symlink)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should yes
@ostrolucky since PHP Array Cache adapter is a decorator for another adapter I'm not sure |
If PHP Array Cache adapter is a decorator for another adapter, what happens right now when |
f1a5aca
to
160b5c1
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please state the obvious. It would be great not to have to read several issues and PRs on different repositories to understand this.
We decorate the existing metadata cache of each entity manager with a PHP Array Cache when not in debug mode. That cache is warmed up by getting all the metadata for all entities.
Since metadata is not supposed to be discovered at runtime, the fallback cache, which is the one configured through this key, is never supposed to be used. There is no point in configuring it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I pushed new commits with explanations that might be completely wrong, please review and amend them if necessary.
It isn't clear to me what I've to change in my application and I'm not the only one: https://stackoverflow.com/questions/64741823/symfony-4-4-metadata-cache-driver-configuration-key-deprecation-notice Can someone explain why this change was needed and how we should replace |
metadata_cache_driver configuration needs to be removed. Change is needed because defining own metadata_cache_driver is useless from now on. |
$phpArrayCacheDecoratorServiceId = $decoratedMetadataCacheServiceId . '.php_array'; | ||
$phpArrayFile = '%kernel.cache_dir%' . sprintf('/doctrine/orm/%s_metadata.php', $entityManagerName); | ||
|
||
$container->register(DoctrineMetadataCacheWarmer::class) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ossinkine actually this is not working properly for multiple entity managers. I just tried it on one of my bigger projects that uses 2 managers.
Since DoctrineMetadataCacheWarmer::class
is the service id it will only work for the last manager and overwrite any previous definitions
Closes #1186
cc @ostrolucky @dmaicher @nicolas-grekas
I see two weak places in this implementation:
DoctrineMetadataCacheWarmer
extendsAbstractPhpFileCacheWarmer
which also extended byValidatorCacheWarmer
,SerializerCacheWarmer
andAnnotationsCacheWarmer
(everywherePhpArrayAdapter
used) but it's marked as internal, so BC breaks possible here. I can avoid extending this class but a lot of code will be copy-pasted.PhpArrayAdapter
requires Symfony cache I wrap Doctrine cache withDoctrineAdapter
. If Doctrine cache isDoctrineProvider
which wrap a Symfony cache we get a redudant chain of adapters. For example the chainPhpArrayAdapter -> DoctrineAdapter -> DoctrineProvider -> RedisAdapter
can be simplified by removingDoctrineAdapter
andDoctrineProvider
:PhpArrayAdapter -> RedisAdapter
. I've tried to create a compiler pass which remove this redundancy but get list of entity managers in compiler pass a little bit difficult. And maybe we can implement this simplification in Symfony framework bundle globally for all such cache chains.What is your opinion about this?