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

Skip to content

[EventDispatcher] Handle laziness internally instead of relying on ClosureProxyArgument #23008

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
Jun 1, 2017

Conversation

nicolas-grekas
Copy link
Member

@nicolas-grekas nicolas-grekas commented Jun 1, 2017

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

If we decide to go this way, we might drop ClosureProxyArgument entirely because we won't need it internally. I'll propose it in another PR for discussion if this one is accepted.

This PR allows "high-order" listeners, as array(Closure, method). Closure is called to get the actual instance when needed only.

How does it look to you? (I'll add tests once confirmed)

Copy link
Member

@chalasr chalasr left a comment

Choose a reason for hiding this comment

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

I think its a nice have for the dispatcher itself and that the bit of complexity added here isn't a big deal as it allows removing much more from DI. 👍
(adding some tests for this would be nice I guess)

@nicolas-grekas nicolas-grekas force-pushed the subscriber-registry branch 2 times, most recently from ded0bb4 to b2a71e2 Compare June 1, 2017 11:23
@nicolas-grekas
Copy link
Member Author

now with simplified logic

@Gemineye
Copy link

Gemineye commented Jun 1, 2017

This patch seems to fix my Issue in #22970. 👍

if ($listeners) {
$this->listeners[$eventName][$priority] = $listeners;
} else {
unset($this->listeners[$eventName][$priority]);
Copy link
Member Author

@nicolas-grekas nicolas-grekas Jun 1, 2017

Choose a reason for hiding this comment

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

this "unset" allows better cleanup of the $this->listeners property and explains the replacement of "isset" by "empty" in a few places above

Copy link
Member Author

Choose a reason for hiding this comment

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

oh, and this most importantly helps the new implem of hasListeners (which is lazy-compliant now)

@weaverryan
Copy link
Member

This also appears to fix #23011

Copy link
Member

@weaverryan weaverryan left a comment

Choose a reason for hiding this comment

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

The isset -> empty change added some complexity, at least for reviewing (could that be done in a separate PR?). But, it makes sense to me, looks good and obviously all the existing tests still pass

} else {
$listeners[$k] = $v;
}
}
Copy link
Member

Choose a reason for hiding this comment

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

Is this identical to the code down in sortListeners()? If so, perhaps a private function resolveListeners($eventName) or something similar? I'm finding some of the logic a bit hard to follow - organizing into a private function(s) might also help me understand things :)

Copy link
Member Author

@nicolas-grekas nicolas-grekas Jun 1, 2017

Choose a reason for hiding this comment

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

not sure about the private: performance is critical in this components

@nicolas-grekas
Copy link
Member Author

nicolas-grekas commented Jun 1, 2017

could that be done in a separate PR?

not without conflicts, which means process overhead, I'd prefer not

@weaverryan
Copy link
Member

👍

@dmaicher
Copy link
Contributor

dmaicher commented Jun 1, 2017

Some tests would be good for it I think 😄 👍

Edit: ah did not see your comment 😉

(I'll add tests once confirmed)

if ($v === $listener) {
unset($listeners[$k], $this->sorted[$eventName]);
} else {
$listeners[$k] = $v;
Copy link
Contributor

Choose a reason for hiding this comment

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

can we not use foreach ($listeners as $k => &$v) { instead?

Copy link
Member Author

Choose a reason for hiding this comment

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

references don't play well with php 5, I try to avoid them as much as possible

@nicolas-grekas nicolas-grekas changed the title [EventDispatcher] Handle lazyness internally instead of relying on ClosureProxyArgument [EventDispatcher] Handle laziness internally instead of relying on ClosureProxyArgument Jun 1, 2017
@nicolas-grekas
Copy link
Member Author

Now with tests

@fabpot
Copy link
Member

fabpot commented Jun 1, 2017

Thank you @nicolas-grekas.

@fabpot fabpot merged commit c17a009 into symfony:3.3 Jun 1, 2017
fabpot added a commit that referenced this pull request Jun 1, 2017
…lying on ClosureProxyArgument (nicolas-grekas)

This PR was merged into the 3.3 branch.

Discussion
----------

[EventDispatcher] Handle laziness internally instead of relying on ClosureProxyArgument

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

If we decide to go this way, we might drop ClosureProxyArgument entirely because we won't need it internally. I'll propose it in another PR for discussion if this one is accepted.

This PR allows "high-order" listeners, as `array(Closure, method)`. Closure is called to get the actual instance when needed only.

How does it look to you? (I'll add tests once confirmed)

Commits
-------

c17a009 [EventDispatcher] Handle laziness internally instead of relying on ClosureProxyArgument
@nicolas-grekas nicolas-grekas deleted the subscriber-registry branch June 1, 2017 20:47
nicolas-grekas added a commit that referenced this pull request Jun 2, 2017
This PR was merged into the 3.3 branch.

Discussion
----------

[Di] Remove closure-proxy arguments

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

With #23008, we don't need this in core anymore.
Let's drop it now.
Technically that's a BC break, but for a feature that is very new, and still quite hidden.
Doing this now would save us from maintaining this code, and help reduce the overall complexity.

Basically reverts #20953

Commits
-------

57daadb [Di] Remove closure-proxy arguments
@fabpot fabpot mentioned this pull request Jun 5, 2017
@vudaltsov
Copy link
Contributor

@nicolas-grekas , am I right that now if I create a subscriber like this:

<?php

namespace AppBundle\EventListener;

use Symfony\Component\EventDispatcher\EventSubscriberInterface;

class TestListener implements EventSubscriberInterface
{
    public function __construct()
    {
        dump('constructor');
    }

    public static function getSubscribedEvents()
    {
        return [
            'test' => 'test',
        ];
    }

    public function test()
    {
        dump('fired');
    }
}

I should not see constructor in the profiler's dump section until the test event is fired?

@stof
Copy link
Member

stof commented Oct 20, 2017

@vudaltsov not exactly. The profiler itself triggers initialization currently, due to collecting not-called listeners, which gets all of them.

@vudaltsov
Copy link
Contributor

@stof , thank you! Now I understand what the problem was... With profiler disabled everything works as expected, so I can rely on this in production.

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.

10 participants