Skip to content
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

[dependency-injection] does not autoconfigure my form extension when another form extension is configured manually in services.yaml #35916

Closed
TomaszGasior opened this issue Mar 1, 2020 · 6 comments

Comments

@TomaszGasior
Copy link

TomaszGasior commented Mar 1, 2020

Symfony version(s) affected: 4.4.5

Description
After updating symfony/dependency-injection from 4.4.4 to 4.4.5 my one form extension is not autoconfigured (tagged) by Symfony framework. If I remove manual configuration of another form extension from services.yaml, the first one is properly autoconfigured (tagged).

How to reproduce

  1. Clone my project: https://github.com/TomaszGasior/RadioLista-v3. Chechout 44f1ef41f1dd115f3405730bc8eaee512d10d325 commit where all dependencies except symfony/dependency-injection are up to date at the moment where I write this text.
  2. bin/phpunit -> tests should pass
  3. Update symfony/dependency-injection to 4.4.5.
  4. bin/phpunit -> Tests related to adding, removing and editing radio stations should fail. Twig templates of these pages rely on variable from RadioStationEditExtension form extension which is not autoconfigured.
  5. Remove manual configuration of App\Form\Extension\ValidationFlashErrorExtension from services.yaml. (My app contains two form extensions. ValidationFlashErrorExtension needs to be set up manually to get special priority.)
  6. bin/phpunit -> tests should pass
TomaszGasior added a commit to TomaszGasior/RadioLista-v3 that referenced this issue Mar 1, 2020
Except for symfony/dependency-injection.
symfony/symfony#35916
@nutama
Copy link

nutama commented Mar 2, 2020

I noticed the same behaviour with the ArgumentValueResolver, but this issue can happen for every service that is autoconfigured. This seems to be related to #35342 .

Before 4.4.5, tagged services are only processed once by the PriorityTaggedServiceTrait. Since 4.4.5, services are processes multiple times, based on the number of tags.

This works fine when:

  • autoconfigure is disabled and you manually tag your services
  • autoconfigure is enabled and you do not manually tag your services with a priority
  • autoconfigure is enabled and you do tag all your services with a priority

This can not work when:

  • autoconfigure is enabled and you mixed manually tagged services with an priority and depend on autoconfiguring

Autoconfigure automaticly add tags to a service.
When you manually define a service that is also autoconfigure, multiple tags are added to the definition.
It can work, cause it depends on the order (abc.. asc) when services are loaded.

For example:

services:
    _defaults:
        autowire: true
        autoconfigure: true

    App\ArgumentResolver\AppArgumentValueResolver:
        tags:
            - { name: controller.argument_value_resolver, priority: 150 }

Then you will a service with the following attributes:

array(2) {
  [0] =>
  array(1) {
    'priority' =>
    int(150)
  }
  [1] =>
  array(0) {
  }
}

The current code in the PriorityTaggedServiceTrait will overwrite services, when there is already a service with priority 0.

The current unittest does not take this case into account, and does not test scenarios with multiple attributes.

Change in test to trigger the bug:

@@ -21,25 +21,25 @@ class PriorityTaggedServiceTraitTest extends TestCase
     public function testThatCacheWarmersAreProcessedInPriorityOrder()
     {
         $services = [
-            'my_service1' => ['my_custom_tag' => ['priority' => 100]],
-            'my_service2' => ['my_custom_tag' => ['priority' => 200]],
-            'my_service3' => ['my_custom_tag' => ['priority' => -501]],
-            'my_service4' => ['my_custom_tag' => []],
-            'my_service5' => ['my_custom_tag' => ['priority' => -1]],
-            'my_service6' => ['my_custom_tag' => ['priority' => -500]],
-            'my_service7' => ['my_custom_tag' => ['priority' => -499]],
-            'my_service8' => ['my_custom_tag' => ['priority' => 1]],
-            'my_service9' => ['my_custom_tag' => ['priority' => -2]],
-            'my_service10' => ['my_custom_tag' => ['priority' => -1000]],
-            'my_service11' => ['my_custom_tag' => ['priority' => -1001]],
-            'my_service12' => ['my_custom_tag' => ['priority' => -1002]],
-            'my_service13' => ['my_custom_tag' => ['priority' => -1003]],
-            'my_service14' => ['my_custom_tag' => ['priority' => -1000]],
-            'my_service15' => ['my_custom_tag' => ['priority' => 1]],
-            'my_service16' => ['my_custom_tag' => ['priority' => -1]],
-            'my_service17' => ['my_custom_tag' => ['priority' => 200]],
-            'my_service18' => ['my_custom_tag' => ['priority' => 100]],
-            'my_service19' => ['my_custom_tag' => []],
+            'my_service1' => ['my_custom_tag' => [['priority' => 100]]],
+            'my_service2' => ['my_custom_tag' => [['priority' => 200]]],
+            'my_service3' => ['my_custom_tag' => [['priority' => -501]]],
+            'my_service4' => ['my_custom_tag' => [[]]],
+            'my_service5' => ['my_custom_tag' => [['priority' => -1]]],
+            'my_service6' => ['my_custom_tag' => [['priority' => -500]]],
+            'my_service7' => ['my_custom_tag' => [['priority' => -499]]],
+            'my_service8' => ['my_custom_tag' => [['priority' => 1]]],
+            'my_service9' => ['my_custom_tag' => [['priority' => -2]]],
+            'my_service10' => ['my_custom_tag' => [['priority' => -1000]]],
+            'my_service11' => ['my_custom_tag' => [['priority' => -1001]]],
+            'my_service12' => ['my_custom_tag' => [['priority' => -1002]]],
+            'my_service13' => ['my_custom_tag' => [['priority' => -1003]]],
+            'my_service14' => ['my_custom_tag' => [['priority' => -1000]]],
+            'my_service15' => ['my_custom_tag' => [['priority' => 1]]],
+            'my_service16' => ['my_custom_tag' => [['priority' => -1]]],
+            'my_service17' => ['my_custom_tag' => [['priority' => 200]]],
+            'my_service18' => ['my_custom_tag' => [['priority' => 100], []]],
+            'my_service19' => ['my_custom_tag' => [[]]],
         ];
 
         $container = new ContainerBuilder();
@@ -48,7 +48,9 @@ class PriorityTaggedServiceTraitTest extends TestCase
             $definition = $container->register($id);
 
             foreach ($tags as $name => $attributes) {
-                $definition->addTag($name, $attributes);
+                foreach ($attributes as $attribute) {
+                    $definition->addTag($name, $attribute);
+                }
             }
         }

As result: my_service18 will now overwrite / remove my_service4

@apfelbox
Copy link
Contributor

apfelbox commented Mar 3, 2020

This is a breaking bug in Symfony 4.4.5 / 5.0.5, as some services are just randomly disappearing

Fix for now: pin the version to 4.4.4 / 5.0.4

FYI: @nicolas-grekas

edit: on a really low level, the problem seems to be that the $index in the trait method isn't unique but is reused. That's why later services overwrite earlier services with the same priority.

@nicolas-grekas
Copy link
Member

/cc @alex-dev also - anyone up for submitting a PR?

@alex-dev
Copy link
Contributor

alex-dev commented Mar 4, 2020

I'll check it. Seems like I caused the regression.

@nicolas-grekas
Copy link
Member

I just fixed this: #35957

@TomaszGasior
Copy link
Author

@nicolas-grekas I confirm that your PR fixes my original issue.

nicolas-grekas added a commit that referenced this issue Mar 5, 2020
…ityTaggedServiceTrait (nicolas-grekas)

This PR was merged into the 4.4 branch.

Discussion
----------

[DI] ignore extra tags added by autoconfiguration in PriorityTaggedServiceTrait

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

Commits
-------

09770aa [DI] ignore extra tags added by autoconfiguration in PriorityTaggedServiceTrait
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

7 participants