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

Adding unit tests showing #3037 #7407

Closed
wants to merge 12 commits into from
Closed

Conversation

sandvige
Copy link

@sandvige sandvige commented Sep 24, 2018

@sandvige
Copy link
Author

All tests are passing, except the one related to code coverage (it appears to be stuck). It is possible this dirty fix is implying a few quirks on performances (It's keep ALL entities, ever tracked), so it is possible this array is pretty big and the coverage is not very happy.

$this->_em->flush();

$articles = [];
for($i=0;$i<100;$i++) {
Copy link
Member

Choose a reason for hiding this comment

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

Can we reproduce this with just two?

Copy link
Author

@sandvige sandvige Sep 25, 2018

Choose a reason for hiding this comment

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

The problem is the underlying GC implementation. With PHP 5.6, it is triggering the assert at the 85th entity. With PHP7, it's at the 100th. I think the problem is based on how the internal implementation of PHP is choosing among the available memory slots. When I try with 2, nothing happen.

Copy link
Member

Choose a reason for hiding this comment

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

PHP 5.6 is generally not relevant - what's important is to verify PHP 7. The fact that it acts on the very last iteration, yet we can't reduce the iteration count to just 2 means that we don't fully understand the problem yet.

Copy link
Author

Choose a reason for hiding this comment

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

Well, we're talking about how PHP is recycling memory. What if PHP is storing available memory slots into an hashmap? It would result into something more or less random, this is why having a lot of slots having the same size being available (due to recycling) is making this error to happens more frequently. This unit tests is just showing the problem, but there's too much random factor in this bug. Keep in mind that this is happening, and why: the documentation about spl_object_hash is clear: ids are recycled, thus not unique in time. My fix is pretty simple, it just ensure the UOW is still holding a reference on managed entities to avoid this pitfall. To be honest, I don't understand why we need a unit tests for this case, this is part of the way PHP is handling memory. And we DO have a unit test that is showing the issue, what a chance :). I think we do understand what is happening here, this is why the unit test is "statically working". I think this unit test should NOT be merged into the core as PHP might change the way it handles memory in the future. This fix is important as long as the UOW is using spl_object_hash (and spl_object_id for PHP7).

Copy link
Member

Choose a reason for hiding this comment

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

I know that object hashes are being recycled, but writing a test that relies on random optimisations is incorrect.

A better test would then be to check all array keys of all UnitOfWork properties to make sure the object hash is gone for good from anywhere, because this particular test is otherwise too fragile.

$this->_em->flush();

$articles = [];
for($i=0;$i<100;$i++) {
Copy link
Author

@sandvige sandvige Sep 25, 2018

Choose a reason for hiding this comment

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

The problem is the underlying GC implementation. With PHP 5.6, it is triggering the assert at the 85th entity. With PHP7, it's at the 100th. I think the problem is based on how the internal implementation of PHP is choosing among the available memory slots. When I try with 2, nothing happen.

@@ -1622,9 +1633,10 @@ public function removeFromIdentityMap($entity)

$className = $classMetadata->rootEntityName;

unset($this->oidMap[$oid]);
unset($this->readOnlyObjects[$oid]);
Copy link
Author

Choose a reason for hiding this comment

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

There's exactly the same issue with the read only objects: they can points at dead entities. We have to clear the oid even if the entity is not found into the identityMap.

@sandvige
Copy link
Author

I don't understand why the code coverage is stuck with my implementation. Is there something asserting (when using coverage only) something on the object layout of the UOW?

@sandvige
Copy link
Author

@Ocramius a build failed on travis because of this:

$ phpenv global 7.2 2>/dev/null
7.2 is not pre-installed; installing
Downloading archive: https://s3.amazonaws.com/travis-php-archives/binaries/ubuntu/14.04/x86_64/php-7.2.tar.bz2
404.01s$ curl -s -o archive.tar.bz2 $archive_url && tar xjf archive.tar.bz2 --directory /
curl: (56) SSL read: error:00000000:lib(0):func(0):reason(0), errno 104
0.01s0.03s$ phpenv global 7.2
rbenv: version `7.2' not installed
The command "phpenv global 7.2" failed and exited with 1 during .
Your build has been stopped.

Do you want to restart the build, because as a project maintainer, I'm pretty sure you have this button, or should I bump the PR with a fake commit?

@lcobucci
Copy link
Member

@sandvige I've restarted the build. Could you please rebase this branch on top of 2.7 instead of merging things in here? It would be slightly better for reviews if we don't have all these unnecessary merge commits.

@sandvige
Copy link
Author

@lcobucci Done.

@bigfoot90
Copy link

bigfoot90 commented Aug 27, 2021

Are there any news on this?
I'm also facing this issue, tried to apply this changes on my project and it's working very well for me, I'm using doctrine/orm:2.9.5 on php7.4.
Should I create a new MR from branch 2.9.x?
Please tell me if I ca do something to help.
Thanks

@greg0ire
Copy link
Member

Should I create a new MR from branch 2.9.x?

Yes, that would be helpful I think! I need to read the comments on this PR to see what's missing, but let's try this 👍

@bigfoot90
Copy link

@greg0ire Created new PR of this changes from 2.9.x in #8994

@mpdude
Copy link
Contributor

mpdude commented Jun 23, 2023

@sandvige maybe you want to join #10791

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

10 participants