Open warkadiuszz opened 7 months ago
I'm not sure if using database during application bootstrap is even legal
As you can see, that usage is tricky.
Another thing is – I'm not sure if the order of those functions calls can be changed at all and if it won't be a breaking change for anyone else.
Likely it would break something. @SamMousa since you did that rework, do you remember order change reasoning?
I don't see an issue directly with changing the order. When do we remove class level event listeners? If we don't do that before starting the app in startApp it should be fine
Hello,
after adding a function to the boostrap of my Yii2 application, a lot of my tests stopped working. For all of them it was always one of two reasons:
TooManyConnections
(just as the other old issues that happened in the past in that module, eg. here and here).All tests started working again immediately after removing the function in boostrap. Imporantly, the additional code in the boostrap uses database. For example (config
main.php
):Explanation / debugging / working fix
What I was able to find out is that both
ConnectionWatcher
andTransactionForcer
classes work by hooking toConnection::EVENT_AFTER_OPEN
event. When some code inboostrap
uses database, before those two watchers are set up, theEVENT_AFTER_OPEN
happens before them, so they never trigger.The order of the code in
Module/Yii2::_before
(here) is:Application
boostrap
happens at step (1) -startApp
. If database is used at that point,Connection::EVENT_AFTER_OPEN
also happens. Then the handlers created by (2), (3) and (4) never work again(?), because they are waiting for that event to happen.If instead the
startApp
is called last:Then both
ConnectionWatcher
andTransactionForcer
(startTransactions()
) bind toConnection::EVENT_AFTER_OPEN
before bootstrap so they work correctly.Steps to reproduce
In application config add function that calls DB:
Create a test with 2 cases that relies on data being cleaned between them:
namespace app\tests\unit;
use Codeception\Test\Unit;
class SomeTest extends Unit { public function testCaseOne(): void { // Ensure no records are present in DB
$this->assertEquals(0, SomeModel::find()->count());
}