diff --git a/src/DependencyInjection/Configurator.php b/src/DependencyInjection/Configurator.php index 49cc9f546df..5341f38ed25 100644 --- a/src/DependencyInjection/Configurator.php +++ b/src/DependencyInjection/Configurator.php @@ -145,6 +145,7 @@ private function journal(string $currentContainerClassName): void $linesToWrite = []; $usedInTheLastWeek = []; $now = time(); + $week = 3600 * 24 * 7; $currentAlreadyInTheJournal = false; foreach ($journalLines as $journalLine) { if ($journalLine === '') { @@ -157,8 +158,6 @@ private function journal(string $currentContainerClassName): void $className = $journalLineParts[0]; $containerLastUsedTime = (int) $journalLineParts[1]; - $week = 3600 * 24 * 7; - if ($containerLastUsedTime + $week < $now) { continue; } @@ -200,6 +199,11 @@ private function journal(string $currentContainerClassName): void if (in_array($fileClassName, $usedInTheLastWeek, true)) { continue; } + // another PHPStan process sharing this directory writes a new container before it is + // journaled, so a file missing from the journal is deleted only once it is a week old + if ($fileInfo->getMTime() + $week >= $now) { + continue; + } $basePathname = $fileInfo->getPathname(); @unlink($basePathname); @unlink($basePathname . '.lock'); diff --git a/tests/PHPStan/DependencyInjection/ConfiguratorJournalTest.php b/tests/PHPStan/DependencyInjection/ConfiguratorJournalTest.php new file mode 100644 index 00000000000..d7e5465c552 --- /dev/null +++ b/tests/PHPStan/DependencyInjection/ConfiguratorJournalTest.php @@ -0,0 +1,60 @@ +tempDirectory = sys_get_temp_dir() . '/' . uniqid('phpstan-configurator-journal-', true); + } + + #[Override] + protected function tearDown(): void + { + FileSystem::delete($this->tempDirectory); + } + + public function testKeepsAContainerThatAnotherProcessHasNotJournaledYet(): void + { + $configurator = new Configurator(new LoaderFactory(new FileHelper(__DIR__), __DIR__, __DIR__, null, []), true); + $configurator->setTempDirectory($this->tempDirectory); + $directory = $configurator->getContainerCacheDirectory(); + FileSystem::createDir($directory); + + $now = time(); + $eightDaysAgo = $now - 3600 * 24 * 8; + file_put_contents($directory . '/container.journal', sprintf("Container_used:%d\nContainer_expired:%d\n", $now, $eightDaysAgo)); + foreach (['Container_used', 'Container_expired', 'Container_current', 'Container_unjournaled'] as $className) { + file_put_contents($directory . '/' . $className . '.php', ' $this->journal('Container_current'))->call($configurator); + + $this->assertFileExists($directory . '/Container_used.php'); + $this->assertFileExists($directory . '/Container_current.php'); + $this->assertFileExists($directory . '/Container_fresh.php'); + $this->assertFalse(is_file($directory . '/Container_expired.php')); + $this->assertFalse(is_file($directory . '/Container_unjournaled.php')); + } + +}