My question is about more philosophical than technical issues.
A few words about Doctrine`s EM. It closes connection and clear itself if any exception occurred during it work: connection to database failed (common case in long-running consumers with low number of incoming tasks), error in SQL statement, or something else, related to DB-server, or EM itself. After this EM instance is completely unusable.
So, real-world example: i have a queue and consumer, that`s running as console worker and wait for tasks. Consumer has next dependencies:
- EntityManager (EM)
- Service1 -> has dependency from EM and Doctrine Repository1
- Service2 -> has dependency from EM and Doctrine Repository2
- ServiceN -> has dependency from EM and Doctrine RepositoryN
If EM service is failed - Service(1-N) and Repository(1-N), that depends on this EM, will be also throw errors when called, because EM is no longer works correctly. What I should do in this case?
- "let-it-crash": worker stoppped with error and later reloaded by supervisord. Leads to increase number of useless errors in logs\stderr.
- do some magic with
$connection->ping()
in each iteration: actually,ping()
just executeSELECT 1;
, so, this leads to increase number of useless queries to DB server. - same as before, but in case of EM fail create new one on consumer: execute
ping()
on each iteration, if it failed - create new EM. But, all services used in consumer should be also re-created, so I need a Factory for each of them. This way leads to increase number of classes and more complicated logic in consumer: re-create all services (and it dependencies) on each iteration with new, or old EM, or detect EM re-creation and re-create all dependent services only in case of new EM. But this leads to abstaction leak: consumer should not know what EM instance it uses - old or new, and should not do this crappy things.
What is the best way to deal with this things?