Thanks to visit codestin.com
Credit goes to github.com

Skip to content

[DependencyInjection] Fix PriorityTaggedServiceTrait for AsTaggedItem #47406

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

Closed
wants to merge 1 commit into from

Conversation

moesoha
Copy link
Contributor

@moesoha moesoha commented Aug 27, 2022

Q A
Branch? 5.4
Bug fix? yes
New feature? no
Deprecations? no
Tickets n/a
License MIT
Doc PR n/a

If $tagName is string, $defaultPriorityMethod will be null, and PriorityTaggedServiceUtil::getDefault won't work for tagged services. This will cause AsTaggedItem not working for these tag names.

@carsonbot carsonbot added this to the 5.4 milestone Aug 27, 2022
@moesoha moesoha force-pushed the fix/AsTaggedItem branch 2 times, most recently from a18f9a5 to bd1273b Compare August 27, 2022 11:46
@carsonbot
Copy link

Hey!

I think @ruudk has recently worked with this code. Maybe they can help review this?

Cheers!

Carsonbot

@ruudk
Copy link
Contributor

ruudk commented Aug 31, 2022

Could you please add some tests cases that show this fix is needed.

If `$tagName` is string, `$defaultPriorityMethod` will be null, and `PriorityTaggedServiceUtil::getDefault` won't work for tagged services. This will cause `AsTaggedItem` not working for these tag names.
@moesoha
Copy link
Contributor Author

moesoha commented Sep 2, 2022

@ruudk I have added assertions for this condition.

@moesoha
Copy link
Contributor Author

moesoha commented Sep 15, 2022

@ruudk are there any updates with this pr?

@ruudk
Copy link
Contributor

ruudk commented Sep 19, 2022

I checked it out but don't really understand what this fixes and how it's needed. But I just wanted you to add tests because that is something the Symfony reviewers will require anyway. So you have to ask somebody from the core team to have a look.

@stof
Copy link
Member

stof commented Sep 19, 2022

Please describe exactly the case that is broken right now (with examples for instance). Evaluating a fix for an issue that is not fully understood is hard.

@moesoha
Copy link
Contributor Author

moesoha commented Sep 30, 2022

@stof I have added a test case to check this problem, you can find it in PriorityTaggedServiceTraitTest.php.

The problem is quite simple: when iterating services with $tagName instead of TaggedIteratorArgument, and the service is described with AsTaggedItem, the priority defined in AsTaggedItem will not work.

@moesoha
Copy link
Contributor Author

moesoha commented Oct 22, 2022

@stof any update?

@moesoha
Copy link
Contributor Author

moesoha commented Dec 5, 2022

PING @stof

@kbond
Copy link
Member

kbond commented Dec 5, 2022

I can confirm this problem but this solution did not work for me.

I have an interface marked with AutoconfigureTag and one of the implementations marked with AsTaggedItem(priority: 10). When injecting using TaggedIterator, the priority is ignored. I had to use AutoconfigureTag on the implementation I want priority 10 for it to work.

Are we talking about the same problem?

@kbond
Copy link
Member

kbond commented Dec 6, 2022

I've created a reproducer that demonstrates my problem: https://github.com/kbond/symfony-reproducer/tree/as-tagged-item (commit). When running bin/console debug:container --tag some_tag you can see the priority from AsTaggedItem is ignored. /cc @nicolas-grekas.

@moesoha
Copy link
Contributor Author

moesoha commented Dec 7, 2022

I've created a reproducer that demonstrates my problem: https://github.com/kbond/symfony-reproducer/tree/as-tagged-item (commit). When running bin/console debug:container --tag some_tag you can see the priority from AsTaggedItem is ignored. /cc @nicolas-grekas.

@kbond In your reproduce repo, I added a command and used the following code to inject implementations:

#[AsCommand('app:test')]
class TestCommand extends Command {
    public function __construct(#[TaggedIterator('some_tag')] iterable $services) {
        var_dump(iterator_to_array($services));
        parent::__construct();
    }
    public function execute(InputInterface $input, OutputInterface $output): int { return Command::SUCCESS; }
}

Adjusted priority attributed on SomeImplementation does make the order change correctly. That means this works correctly.

As a supplement, here is the Kernel class for your repo to reproduce the problem this PR fixes:

class Kernel extends BaseKernel {
    use MicroKernelTrait;
    protected function build(ContainerBuilder $container) {
        $container->addCompilerPass(new class implements CompilerPassInterface {
            use PriorityTaggedServiceTrait;
            public function process(ContainerBuilder $container) {
                var_dump($this->findAndSortTaggedServices(
                    'some_tag', // BAD
                    $container
                ));
                var_dump($this->findAndSortTaggedServices(
                    new TaggedIteratorArgument('some_tag'), // GOOD
                    $container
                ));
            }
        });
    }
}

After applying my patch, the two var_dump print the good value.

But I can confirm there is a bug in DebugBundle (already noticed when I was composing this PR), debug:container cannot display index/priority defined by AsTaggedItem (actually configured and works in the container) because of the way it gets the values.

@kbond
Copy link
Member

kbond commented Dec 7, 2022

Ah, thanks @moesoha! I've confirmed the AsTaggedItem works in my app - it's just not displaying in debug:container as you say.

To clarify, my issue is is a separate problem in debug:container?

@moesoha
Copy link
Contributor Author

moesoha commented Dec 7, 2022

@kbond exactly.

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'm sorry but this looks incorrect to me: AsTaggedItem is supposed to work together with TaggedIteratorArgument. That's what the word "Tagged" means in the name of the attribute. When not requesting for "tagged" items, the returned array should be a regular list.

When did you encounter this behavior? If it was in a compiler pass of your own, you need to give this method a TaggedIteratorArgument to get the indexed array.

@nicolas-grekas
Copy link
Member

@kbond your example is the same: AsTaggedItem applies only when requesting for a TaggedIterator, not when "just" getting the list of tags.
#[AutoconfigureTag('some_tag', ['priority' => 10])] is what you might want to add to set the priority for this tag.

I'm closing here because this works as designed. I understand it might not match your expectations, but changing this should be considered as a new feature I guess - not as a bugfix for sure.

Thanks for submitting.

@nicolas-grekas
Copy link
Member

nicolas-grekas commented Dec 14, 2022

One last note on this: if we were to implement something like you expected, I'd suggest doing it via a tag, eg
['default_attributes', ['priority' => 10]], and we could of course add a dedicated attribute to make it easier to define this tag.

(or maybe ['default_attributes', ['some_tag' => ['priority' => 10]]] for more specificity?).

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.

6 participants