Skip to content

[FrameworkBundle] Fix using annotation_reader in compiler pass to inject configured cache provider #26088

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

Merged
merged 1 commit into from
Feb 19, 2018
Merged

[FrameworkBundle] Fix using annotation_reader in compiler pass to inject configured cache provider #26088

merged 1 commit into from
Feb 19, 2018

Conversation

Laizerox
Copy link
Contributor

@Laizerox Laizerox commented Feb 8, 2018

Q A
Branch? 3.4
Bug fix? yes
New feature? no
BC breaks? no
Deprecations? no
Tests pass? yes
Fixed tickets #26086
License MIT
Doc PR -

The compilation pass of AddAnnotationsCachedReaderPass relies on already removed definition annotations.cached_reader due to an alias to annotation_reader.

Since the definition is being removed because of alias, configured annotation cache provider is not injected and will default back to ArrayCache.

This PR replaces the use of annotations.cached_reader to annotation_reader to complete the injection of configured cache provider.

@Laizerox Laizerox changed the title Fix annotation cache inject [FrameworkBundle] Fix annotation cache inject Feb 8, 2018
@Laizerox Laizerox changed the base branch from 3.3 to 3.4 February 8, 2018 09:58
@linaori
Copy link
Contributor

linaori commented Feb 8, 2018

Can you add tests for this?

@nicolas-grekas nicolas-grekas added this to the 3.4 milestone Feb 9, 2018
@nicolas-grekas nicolas-grekas changed the title [FrameworkBundle] Fix annotation cache inject [FrameworkBundle] Fix using annotation_reader in compiler pass to inject configured cache provider Feb 19, 2018
Copy link
Member

@nicolas-grekas nicolas-grekas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(I just added a test case)

@nicolas-grekas
Copy link
Member

Thank you @Laizerox.

@nicolas-grekas nicolas-grekas merged commit dfd93da into symfony:3.4 Feb 19, 2018
nicolas-grekas added a commit that referenced this pull request Feb 19, 2018
…pass to inject configured cache provider (Laizerox)

This PR was merged into the 3.4 branch.

Discussion
----------

[FrameworkBundle] Fix using annotation_reader in compiler pass to inject configured cache provider

| Q             | A
| ------------- | ---
| Branch?       | 3.4
| Bug fix?      | yes
| New feature?  | no
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | #26086
| License       | MIT
| Doc PR        | -

The compilation pass of AddAnnotationsCachedReaderPass relies on already removed definition `annotations.cached_reader` due to an alias to `annotation_reader`.

Since the definition is being removed because of alias, configured annotation cache provider is not injected and will default back to ArrayCache.

This PR replaces the use of `annotations.cached_reader` to `annotation_reader` to complete the injection of configured cache provider.

Commits
-------

dfd93da bug #26086 [FrameworkBundle] Fix using annotation_reader in compiler pass to inject configured cache provider
@Strate
Copy link
Contributor

Strate commented Mar 1, 2018

Version 3.3 is affected too, could you please backport?

@nicolas-grekas
Copy link
Member

@Strate 3.3 is EOLed, see supported versions on https://symfony.com/roadmap

@Strate
Copy link
Contributor

Strate commented Mar 1, 2018

For all, who want to get it fixed in 3.3, you can add this compiler pass to your container build:

    if ($container->hasDefinition('annotation_reader')) {
            $reader = $container->getDefinition('annotation_reader');
            if (is_a($reader->getClass(), CachedReader::class, true)) {
                $properties = $reader->getProperties();

                if (isset($properties['cacheProviderBackup'])) {
                    $provider = $properties['cacheProviderBackup']->getValues()[0];
                    unset($properties['cacheProviderBackup']);
                    $reader->setProperties($properties);
                    $container->set('annotation_reader', null);
                    $container->setDefinition('annotation_reader', $reader->replaceArgument(1, $provider));
                }
            }
        }

This was referenced Mar 1, 2018
@Laizerox Laizerox deleted the fix-annotation-cache-inject branch March 5, 2018 10:17
@Strate
Copy link
Contributor

Strate commented Apr 6, 2018

Unfortunatelly, this is still actual for all versions for case, when annotation_reader decorated:

ignore_closure_annotations_reader:
        decorates: annotation_reader
        class: IgnoreClosureAnnotationsReader
        arguments: ['@ignore_closure_annotations_reader.inner']
        public: false

It happens, because DecoratorServicePass removes any tag from decorated service and run before AddAnnotationsCachedReaderPass, so late pass can't find any service. I think we can just iterate all services to search CachedReader class and with set cacheProviderBackup property

UPD. Also AddAnnotationsCachedReaderPass run after optimizations, so decorated service no more available in container by id, so I forced to write custom compiler pass special for that case:

public function process(ContainerBuilder $container)
    {
        $def = $container->findDefinition('annotation_reader');
        if (is_a($def->getClass(), IgnoreClosureAnnotationsReader::class, true)) {
            $inner = $def->getArgument(0);
            if ($inner instanceof Definition) {
                $properties = $inner->getProperties();
                if (isset($properties['cacheProviderBackup'])) {
                    if (is_a($inner->getClass(), CachedReader::class, true)) {
                        $provider = $properties['cacheProviderBackup']->getValues()[0];
                        unset($properties['cacheProviderBackup']);
                        $inner->setProperties($properties);
                        $inner->replaceArgument(1, $provider);
                    }
                }
            }
        }
    }

Unfortunatelly, after hitting this issue twice, I can consider that something globally get wrong this wiring process of annotations cache :(

nicolas-grekas added a commit that referenced this pull request May 23, 2022
…(nicolas-grekas)

This PR was merged into the 4.4 branch.

Discussion
----------

[FrameworkBundle] fix wiring of annotations.cached_reader

| Q             | A
| ------------- | ---
| Branch?       | 4.4
| Bug fix?      | yes
| New feature?  | no
| Deprecations? | no
| Tickets       | Fix #46202
| License       | MIT
| Doc PR        | -

Also fixes #26088 (comment)

Instead of trying to hack the compilation of the container to prevent it from inlining `annotations.cached_reader`, this PR relies on an `container.do_not_inline` tag that just does that, prevent inlining so that removing passes can reliably fetch the corresponding services from the container by id or by tag.

Commits
-------

e32b7b1 [FrameworkBundle] fix wiring of annotations.cached_reader
symfony-splitter pushed a commit to symfony/framework-bundle that referenced this pull request May 23, 2022
…(nicolas-grekas)

This PR was merged into the 4.4 branch.

Discussion
----------

[FrameworkBundle] fix wiring of annotations.cached_reader

| Q             | A
| ------------- | ---
| Branch?       | 4.4
| Bug fix?      | yes
| New feature?  | no
| Deprecations? | no
| Tickets       | Fix #46202
| License       | MIT
| Doc PR        | -

Also fixes symfony/symfony#26088 (comment)

Instead of trying to hack the compilation of the container to prevent it from inlining `annotations.cached_reader`, this PR relies on an `container.do_not_inline` tag that just does that, prevent inlining so that removing passes can reliably fetch the corresponding services from the container by id or by tag.

Commits
-------

e32b7b15ec [FrameworkBundle] fix wiring of annotations.cached_reader
symfony-splitter pushed a commit to symfony/framework-bundle that referenced this pull request Jul 28, 2023
…(nicolas-grekas)

This PR was merged into the 4.4 branch.

Discussion
----------

[FrameworkBundle] fix wiring of annotations.cached_reader

| Q             | A
| ------------- | ---
| Branch?       | 4.4
| Bug fix?      | yes
| New feature?  | no
| Deprecations? | no
| Tickets       | Fix #46202
| License       | MIT
| Doc PR        | -

Also fixes symfony/symfony#26088 (comment)

Instead of trying to hack the compilation of the container to prevent it from inlining `annotations.cached_reader`, this PR relies on an `container.do_not_inline` tag that just does that, prevent inlining so that removing passes can reliably fetch the corresponding services from the container by id or by tag.

Commits
-------

e32b7b15ec [FrameworkBundle] fix wiring of annotations.cached_reader
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants