Race Condition при включенной автогенерации гидраторов Doctrine ORM

Как-то раз столкнулись с очень странной ошибкой. Периодически на продакшене вылетал то один то другой запрос с ошибкой PHP Fatal error: Class ‘Hydrators\VendorDefaultBundleDocumentUserHydrator’ not found in /web/vendor/doctrine/mongodb-odm/lib/Doctrine/ODM/MongoDB/Hydrator/HydratorFactory.php.

Проблема

Что было очень странно, так как файл гидратора спокойно лежал по этому пути. При проверке на  develop-машине подобный баг не воспроизводился, только под нагрузкой. Довольно долго гадали, в чём там дело, пока наш доблестный админ не обратил внимание на время изменение файлов гидраторов. Оно постоянно менялось на текущее. А это значит, что гидраторы постоянно перезаписывались. Не буду говорить, как это фигово с точки зрения производительности. Но кроме того, при наличии двух одновременных запросов, первый из них начинал генерировать гидратор, а второй не находил файл и падал. Главное условие одновременность запросов.

Решение

Солюшен прост. Надо сделать так, чтобы на боевом сервере прокси классы и гидраторы генерировались один раз при деплое, а потом не перегенерялись при запросах. Примерно так:

После этого гидраторы перестали перегенеряться и ошибка пропала.

Leave a Comment