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

Fix Doctrine source iterators #380

Merged

Conversation

ossinkine
Copy link
Contributor

Subject

I am targeting this branch, because I've faced with BC break.
After refactoring source iterators here #343 there was lost detaching objects from object managers what led to memory leaks.

Changelog

### Fixed
- Memory leaks in Doctrine source iterators

@ossinkine
Copy link
Contributor Author

@VincentLanglet Please confirm you just lost this but did not remove this intentionally

@VincentLanglet
Copy link
Member

@VincentLanglet Please confirm you just lost this but did not remove this intentionally

Wasn't intentional indeed, since I don't even know what it does.

@VincentLanglet VincentLanglet requested a review from a team September 28, 2020 15:42
Copy link
Member

@VincentLanglet VincentLanglet left a comment

Choose a reason for hiding this comment

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

Oh.

I just see that the method detach is deprecated

@deprecated 2.7 This method is being removed from the ORM and won't have any replacement

Maybe it's the reason I removed it (?).

@greg0ire any opnion on this ?

@ossinkine
Copy link
Contributor Author

Let's just remove all deprecated method calls but not replace them with correct functions 🤣

@VincentLanglet
Copy link
Member

Let's just remove all deprecated method calls but not replace them with correct functions 🤣

Correct function which is ?

src/Source/DoctrineODMQuerySourceIterator.php Outdated Show resolved Hide resolved
src/Source/DoctrineORMQuerySourceIterator.php Outdated Show resolved Hide resolved
@ossinkine
Copy link
Contributor Author

@VincentLanglet @franmomu Actually I've just reverted changes which breack BC but if you want I'll apply your requested changes

@VincentLanglet
Copy link
Member

@VincentLanglet @franmomu Actually I've just reverted changes which breack BC but if you want I'll apply your requested changes

The request change for the Document manager seems easy to apply and avoid using an internal method.

I don't know how hard would be the request change for entityManager

  • If you're motivated to apply the request change and rely on clear, this would be perfect
  • If not, I can understand this, and I'll still approve since it fixes the BC-break.

@ossinkine
Copy link
Contributor Author

I've replaced detach with clear

@franmomu
Copy link
Member

To be honest, I'm not sure about this. I guess there won't be memory leaks, but maybe we are introducing some problems performance-wise. Based on how Doctrine shows how to to batch processing, the calls to EntityManager::clear() are made every X iterations, I guess clearing the whole identity map every iteration is not ideal, but as I said, maybe I'm wrong.

So IMHO, if we don't have enough knowledge about this, I would leave as it was and just replace the call to the @internal function.

@VincentLanglet
Copy link
Member

Indeed, maybe it's safer to use

$this->query->getDocumentManager()->detach($current[0]);

for ODM

And keep

$this->query->getEntityManager()->getUnitOfWork()->detach($current[0]);

for ORM until we get some help to remove the deprecated method (maybe @greg0ire you can help us ?)

@ossinkine
Copy link
Contributor Author

ossinkine commented Sep 30, 2020

Actually the calling clear in the source iterator is safe because all other entities are not used here, it just read entities from iterator and put them in the response and that's all.

I also think that using deprecated functions is acceptable as opposed to internal ones because BC is guaranteed here. So we can just using $this->query->getDocumentManager()->detach($current[0]); and $this->query->getEntityManager()->detach($current[0]); here and will improve this in the future.

@greg0ire
Copy link
Contributor

After reading that conversation, I think this PR looks fine and clear() is the way to go: doctrine/orm#7901 (comment)

Based on how Doctrine shows how to to batch processing, the calls to EntityManager::clear() are made every X iterations, I guess clearing the whole identity map every iteration is not ideal, but as I said, maybe I'm wrong.

flush() is obviously expensive because it will trigger SQL queries. clear(), on the other hand, just clears things that exist in memory. If you need more convincing, just read the code, it will take literally 30 seconds if you bear in mind that $entityName is null: https://github.com/doctrine/orm/blob/79cdcde9ec2b6ea4ca118959842df7860effa2dd/lib/Doctrine/ORM/UnitOfWork.php#L2498-L2526 The only shady thing is the event dispatching: if you have an event plugged on clear, and it's not performant, there will be issues, but I don't think that's something that happens that frequently in the wild.

@VincentLanglet VincentLanglet requested a review from a team September 30, 2020 09:47
@phansys
Copy link
Member

phansys commented Sep 30, 2020

IIUC, if we detach an object from the UoW (by calling clear()), that object will be not identified as an object handled by Doctrine anymore. So, if that object ends involved in the Doctrine domain again (during a call to persist() through an association or similar), the UoW will identify that object as a new instance.
I'm sharing this concern because I think that is not the intended behavior.

@greg0ire
Copy link
Contributor

IIUC, if we detach an object from the UoW (by calling clear()), that object will be not identified as an object handled by Doctrine anymore. So, if that object ends involved in the Doctrine domain again (during a call to persist() through an association or similar), the UoW will identify that object as a new instance.

You're right, but that was the previous behavior anyway. detach and clear will result in that same behavior.

@phansys
Copy link
Member

phansys commented Sep 30, 2020

You're right, but that was the previous behavior anyway. detach and clear will result in that same behavior.

I didn't know we were detaching objects.

@ossinkine
Copy link
Contributor Author

@franmomu please review

@franmomu franmomu merged commit b5ea9b1 into sonata-project:2.x Sep 30, 2020
@franmomu
Copy link
Member

Thanks @ossinkine!

@ossinkine
Copy link
Contributor Author

@VincentLanglet @greg0ire Could anyone from you guys create a release with this fix please?

@VincentLanglet
Copy link
Member

Sure, the PR is opened #386

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

Successfully merging this pull request may close these issues.

None yet

6 participants