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

rename error in ProxyGenerator #327

Closed
Draeli opened this Issue Jul 14, 2014 · 22 comments

Comments

Projects
None yet
@Draeli

Draeli commented Jul 14, 2014

Hello,

Actually, I have this hapening, I don't have idea why, I give you my backtrace, this not happen each time I refresh page but some time.

( ! ) Warning: rename(/app/cache/dev/doctrine/orm/Proxies\__CG__MyCommonBundleEntityVisibilityInformation.php.53c3cccd0a5415.53070441,/app/cache/dev/doctrine/orm/Proxies\__CG__MyCommonBundleEntityVisibilityInformation.php): in \vendor\doctrine\common\lib\Doctrine\Common\Proxy\ProxyGenerator.php on line 305

backtrace :

Call Stack
#   Time    Memory  Function    Location
18  0.6984  11450624    Doctrine\ORM\EntityRepository->findOneBy( ) ..\UserManager.php:68
19  0.7052  11784056    Doctrine\ORM\Persisters\BasicEntityPersister->load( )   ..\EntityRepository.php:196
20  0.7709  12390192    Doctrine\ORM\Internal\Hydration\AbstractHydrator->hydrateAll( ) ..\BasicEntityPersister.php:756
21  0.7709  12390280    Doctrine\ORM\Internal\Hydration\SimpleObjectHydrator->hydrateAllData( ) ..\AbstractHydrator.php:140
22  0.7710  12395136    Doctrine\ORM\Internal\Hydration\SimpleObjectHydrator->hydrateRowData( ) ..\SimpleObjectHydrator.php:48
23  0.7715  12411464    Doctrine\ORM\UnitOfWork->createEntity( )    ..\SimpleObjectHydrator.php:138
24  0.7869  12653744    Doctrine\Common\Proxy\AbstractProxyFactory->getProxy( ) ..\UnitOfWork.php:2676
25  0.7869  12653832    Doctrine\Common\Proxy\AbstractProxyFactory->getProxyDefinition( )   ..\AbstractProxyFactory.php:119
26  0.7882  12666032    Doctrine\Common\Proxy\ProxyGenerator->generateProxyClass( ) ..\AbstractProxyFactory.php:218
27  0.7930  12695936    rename ( )  ..\ProxyGenerator.php:305
@Ocramius

This comment has been minimized.

Member

Ocramius commented Jul 14, 2014

Is there also a message for the warning?

@Draeli

This comment has been minimized.

Draeli commented Jul 14, 2014

over the backtrace if it's what you expected, no more :(

@Ocramius

This comment has been minimized.

Member

Ocramius commented Jul 14, 2014

Is this a system under high load? Automated proxy generation should be avoided in such cases...

@Draeli

This comment has been minimized.

Draeli commented Jul 14, 2014

I suppose you refer to this ? http://docs.doctrine-project.org/en/2.0.x/reference/configuration.html#auto-generating-proxy-classes-optional

Actually, it's local server and not really high load.

@brunowego

This comment has been minimized.

brunowego commented Mar 12, 2015

+1

1 similar comment
@diegopso

This comment has been minimized.

diegopso commented Oct 7, 2015

+1

@chielsen

This comment has been minimized.

chielsen commented Jan 11, 2016

+1

1 similar comment
@ragboyjr

This comment has been minimized.

ragboyjr commented Feb 12, 2016

👍

@Apezoumon123

This comment has been minimized.

Apezoumon123 commented Sep 23, 2016

somebody help me i have the same problem

@anuragdalia

This comment has been minimized.

anuragdalia commented Oct 27, 2016

+1

@camilom

This comment has been minimized.

camilom commented Oct 31, 2016

I have the same problem, PHP 5.6.24 Symfony 2.8

Warning: rename : Acceso denegado. (code: 5)
in vendor\doctrine\common\lib\Doctrine\Common\Proxy\ProxyGenerator.php at line 306

306 line: rename($tmpFileName, $fileName);

Help pls

@nickrouty

This comment has been minimized.

nickrouty commented Mar 30, 2017

I found this thread to be helpful in tracking down a solution:
See doctrine issue 2907

It talks about the issue generally creeping up when concurrent requests are made, which was the case in my scenario.

You can then look at the advanced configuration in Doctrine docs, this also helped:
Doctrine Advanced Configuration

I ended up setting a configuration setting to set the generate_proxies config param to:
Doctrine\Common\Proxy\AbstractProxyFactory::AUTOGENERATE_FILE_NOT_EXISTS

This will ensure that the file only generates if it doesn't exist yet. Note that this could create problems for you if you update your models/entities and do not clear out the proxy classes cached.

@solody

This comment has been minimized.

solody commented Jun 23, 2017

same problem +1

@Majkl578

This comment has been minimized.

Member

Majkl578 commented Jun 23, 2017

Note that for production environment you should always pre-generate the proxies (i.e. on your CI or during cache warmup) to not rely on lazy generation (which is prone to race conditions).

@zayanit

This comment has been minimized.

zayanit commented Dec 6, 2017

+1 same problem

@alcaeus

This comment has been minimized.

Member

alcaeus commented Dec 7, 2017

I'm going to close this as invalid. The issue described by OP is caused by the operating system. The only way I've managed to reproduce it was in a Docker machine where rename('a/file.tmp', 'a/file'); caused a cross-device rename due to the union filesystem in use there, and even then I didn't get it to consistently break.

Without at least a consistent way to reproduce this, there's nothing for us to fix. So please, instead of being the next person to add a +1 type comment, please provide information that is not yet present or try to build a reproducible test case for the problem. Thank you!

@alcaeus alcaeus closed this Dec 7, 2017

@alcaeus alcaeus added the Invalid label Dec 7, 2017

@alcaeus alcaeus self-assigned this Dec 7, 2017

@ppamment

This comment has been minimized.

ppamment commented Feb 16, 2018

Hi @alcaeus

I think I can help here. We recently updated our Symfony/Doctrine MVC application to use an API driven React frontend. All of a sudden this issue starts popping up on some machines.

Why could that be?
MVC application was making single requests at a time when in dev mode, where we have proxy class generation set to AUTOGENERATE_ALWAYS, which is not something we want to change as it is the most convenient setting.
The new React frontend is making multiple async requests to the Sf/Doctrine backend, and suddenly we get a race condition where a couple of these backend requests are generating and trying to write to that proxy file at the same time.

I tried adding an @ suppressor before the rename call in vendor/doctrine/common/lib/Doctrine/Common/Proxy/ProxyGenerator.php:309 and the problem goes away. I can't say this is the best solution since it is true that you are now not using the newly generated proxy class, but IMO a race condition with proxy generation set to AUTOGENERATE_ALWAYS and concurrent requests is not just possible, but expected and should be addressed. PHP rename function is known to be not race condition safe and this needs to be addressed if you wish to avoid such issues.

In terms of how to reproduce, I would bet that firing ab against a simple doctrine instance with AUTOGENERATE_ALWAYS will do the job (note, im running windows, it's possible other filesystems handle this better than ntfs).

For now I can get by with the @ suppressor. It's not as though I actually need my proxy classes to be regenerated for both of the 2 requests that are milliseconds apart. If I have the time to look into how to make the rename race condition safe I may see if I can put together a PR.

@alcaeus

This comment has been minimized.

Member

alcaeus commented Feb 20, 2018

@ppamment the issue you described is exactly the scenario we don't want to fix by error suppression but rather with cache warmup: you should use AUTOGENERATE_NEVER in high-load conditions as described and pre-warm the cache before sending requests there.

@ppamment

This comment has been minimized.

ppamment commented Feb 20, 2018

@alcaeus like I said I don't think the suppressor is the correct solution either. I'm just saying that it is useful to help pin down the route cause and in my case it's an acceptable solution while developing (much as it goes against my instincts to make a temporary edit to a composer installed vendor package). At least when these things get pushed out to our public servers the suppressor is gone and the proxies are as you suggested pregenerated.

On the other hand I hope you'd agree my own dev machine, receiving at most a few concurrent requests from my locally running frontend is not what you'd call a high load environment. Of course I can set AUTOGENERATE_NEVER but this is not very convenient when developing on your own machine as you then need to regenerate proxies every time you edit an entity which is not very good DX.
There is some information on stackoverflow about how to do a race condition safe rename. I will investigate if I get the time.

Thanks

@Ocramius

This comment has been minimized.

Member

Ocramius commented Feb 20, 2018

@ppamment

This comment has been minimized.

ppamment commented Feb 20, 2018

Root cause*

@ppamment

This comment has been minimized.

ppamment commented Feb 20, 2018

Thanks @Ocramius I hadn't really looked into that option, but I can't see any reason this strategy wouldn't work for local development. It's probably even faster than AUTOGENERATE_ALWAYS as it doesn't hit the disk.
I do like the comment too :)

"
* This strategy is only sane for development, and even then it gives me
* the creeps a little.
"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment