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

Prevent loading class_exists multiple times #161

Closed
wants to merge 1 commit into from

Conversation

jrjohnson
Copy link
Contributor

Implementing @stof's suggestion in #145 (comment)

This is just a pre-2.0 bandaid to help solve the biggest issue where class_exists is added as a loader automatically many many times which is a huge performance killer in testing symfony apps (symfony/symfony#24596). While #137 solves this in applications it doesn't help with tests since they maintain the global static state and start up multiple kernels (and registered loaders) at the same time.

In order to avoid a BC break this only checks for duplicate class exists
loaders at the bottom of the stack.

@Ocramius
Copy link
Member

Ocramius commented Dec 4, 2017

As already stated on that thread, the correct solution would be to add a new specialised endpoint.

// Reset our static cache now that we have a new loader to work with
self::$failedToAutoload = [];
self::$loaders[] = $callable;
if ($callable !== 'class_exists' || !self::isLastLoaderClassExists()) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Please invert this condition and make it early-return. Also space around ! is required.

return false;
}
$lastLoader = self::$loaders[$count - 1];
if (!is_string($lastLoader)) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Please remove this condition, it's not an optimization and is redundant.

protected static function isLastLoaderClassExists() : bool
{
$count = count(self::$loaders);
if (0 === $count) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Here no yoda used will be.

In order to avoid a BC break this only checks for duplicate class exists
loaders at the bottom of the stack.
@jrjohnson
Copy link
Contributor Author

Thanks @Majkl578 I made those changes.

@Ocramius thanks for the feedback. My thinking is that adding a new registerLoaderIfNotExists works, but doesn't solve the problem immediately. It requires work across any package that depends on this one. This solution solves the problem immediately with no risk of BC break. Given that the entire registry is not long for this world it doesn't seem like adding a new method and then updating everything to use it is the right choice. It is your project though and going that route isn't more work for me so if you don't want to merge this I will be happy to go that route.

@Ocramius
Copy link
Member

Ocramius commented Dec 4, 2017

It requires work across any package that depends on this one.

Yes, that is something that was already clear to me - I realize that I'm taking the non-DX solution, but the repeated registration of loaders is something to be fixed elsewhere anyway (like keeping a static singleton reference to the loader in the symfony kernel).

Overall, less magic workarounds, especially in a general-purpose library that is basically used everywhere.

@jrjohnson
Copy link
Contributor Author

This isn't about developer experience it is about where the bug is. The performance killing bug is in this library. It should be fixed here. More importantly it can be fixed here for a huge number of situations with no risk.

@Ocramius
Copy link
Member

Ocramius commented Dec 4, 2017 via email

@stof
Copy link
Member

stof commented Dec 4, 2017

@Ocramius the bug to me is the fact that this library requires using a global state to register loaders. Having to add a global state in Symfony itself to workaround a performance issue related to the global state of this library looks weird to me.

@Ocramius
Copy link
Member

Ocramius commented Dec 4, 2017 via email

@stof
Copy link
Member

stof commented Dec 4, 2017

Well, why forcing to migrate to a new API (that will also disappear in 3.x) when you can make all projects out there benefiting from a better performance by just upgrading, in case they follow the recommendation of registering class_exists itself as loader (i.e. doing what Doctrine 3 will always do)

@Ocramius
Copy link
Member

Ocramius commented Dec 5, 2017 via email

@Ocramius Ocramius self-assigned this Dec 6, 2017
@Ocramius Ocramius added this to the 1.6.0 milestone Dec 6, 2017
@Ocramius
Copy link
Member

Ocramius commented Dec 6, 2017

Handled in #162

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.

4 participants