Skip to content

Commit 60bdd29

Browse files
authored
Merge pull request php-pm#509 from acasademont/file_changes_improvement
File changes detection improvements
2 parents bc6d157 + 1a374dc commit 60bdd29

File tree

1 file changed

+50
-47
lines changed

1 file changed

+50
-47
lines changed

src/ProcessManager.php

Lines changed: 50 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -163,18 +163,6 @@ class ProcessManager
163163
*/
164164
protected $port = 8080;
165165

166-
/**
167-
* @var bool
168-
*/
169-
protected $inChangesDetectionCycle = false;
170-
171-
/**
172-
* Whether the server is in the restart phase.
173-
*
174-
* @var bool
175-
*/
176-
protected $inRestart = false;
177-
178166
/**
179167
* The number of seconds to wait before force closing a worker during a reload.
180168
*
@@ -544,9 +532,7 @@ public function run()
544532
$this->loop->addSignal(SIGUSR2, [$this, 'reloadSlaves']);
545533

546534
if ($this->isDebug()) {
547-
$this->loop->addPeriodicTimer(0.5, function () {
548-
$this->checkChangedFiles();
549-
});
535+
$this->loop->addPeriodicTimer(1, [$this, 'checkChangedFiles']);
550536
}
551537

552538
$loopClass = (new \ReflectionClass($this->loop))->getShortName();
@@ -860,7 +846,7 @@ protected function commandFiles(array $data, ConnectionInterface $conn)
860846
foreach ($recentlyIncludedFiles as $filePath) {
861847
if (file_exists($filePath) && !is_dir($filePath)) {
862848
$this->filesLastMTime[$filePath] = filemtime($filePath);
863-
$this->filesLastMd5[$filePath] = md5_file($filePath, true);
849+
$this->filesLastMd5[$filePath] = md5_file($filePath);
864850
$newFilesCount++;
865851
}
866852
}
@@ -954,43 +940,64 @@ protected function bootstrapFailed($port)
954940
* all other file watching stuff have either big dependencies or do not work under all platforms without
955941
* installing a pecl extension. Also this way is interestingly fast and is only used when debug=true.
956942
*
957-
* @param bool $restartSlaves
958-
*
959943
* @return bool
960944
*/
961-
protected function checkChangedFiles($restartSlaves = true)
945+
public function checkChangedFiles()
962946
{
963-
if ($this->inChangesDetectionCycle) {
947+
//If slaves are starting there's no need to check anything
948+
if ($this->status === self::STATE_STARTING) {
964949
return false;
965950
}
966951

967952
$start = microtime(true);
968953
$hasChanged = false;
969954

970-
$this->inChangesDetectionCycle = true;
971-
972955
clearstatcache();
973956

974957
foreach ($this->filesLastMTime as $filePath => $knownMTime) {
975-
if (!file_exists($filePath) || is_dir($filePath)) {
958+
//If the file is a directory, just remove it from the list of tracked files
959+
if (is_dir($filePath)) {
960+
unset($this->filesLastMd5[$filePath]);
961+
unset($this->filesLastMTime[$filePath]);
962+
976963
continue;
977964
}
978965

979-
$actualFileTime = filemtime($filePath);
980-
$actualFileHash = md5_file($filePath);
981-
982-
if ($knownMTime !== $actualFileTime && $this->filesLastMd5[$filePath] !== $actualFileHash) {
983-
984-
// update tracked entry metadata
985-
$this->filesLastMd5[$filePath] = $actualFileHash;
986-
$this->filesLastMTime[$filePath] = $actualFileTime;
966+
//If the file doesn't exist anymore, remove it from the list of tracked files and restart the workers
967+
if (!file_exists($filePath)) {
968+
unset($this->filesLastMd5[$filePath]);
969+
unset($this->filesLastMTime[$filePath]);
987970

988971
$this->output->writeln(
989-
sprintf("<info>[%s] File %s has changed.</info>", date('d/M/Y:H:i:s O'), $filePath)
972+
sprintf("<info>[%s] File %s has been removed.</info>", date('d/M/Y:H:i:s O'), $filePath)
990973
);
991974
$hasChanged = true;
975+
992976
break;
993977
}
978+
979+
//If the file modification time has changed, update the metadata and check its contents.
980+
if ($knownMTime !== $actualFileTime = filemtime($filePath)) {
981+
//update time metadata
982+
$this->filesLastMTime[$filePath] = $actualFileTime;
983+
if ($this->output->isVeryVerbose()) {
984+
$this->output->writeln(
985+
sprintf("File %s mtime has changed, now checking its contents", $filePath)
986+
);
987+
} //Only if the time AND contents have changed restart, touch() seems to change the file mtime
988+
if ($this->filesLastMd5[$filePath] !== $actualFileHash = md5_file($filePath)) {
989+
var_dump($this->filesLastMd5[$filePath], $actualFileHash);
990+
//update file hash metadata
991+
$this->filesLastMd5[$filePath] = $actualFileHash;
992+
993+
$this->output->writeln(
994+
sprintf("<info>[%s] File %s has changed.</info>", date('d/M/Y:H:i:s O'), $filePath)
995+
);
996+
$hasChanged = true;
997+
998+
break;
999+
}
1000+
}
9941001
}
9951002

9961003
if ($hasChanged) {
@@ -1002,18 +1009,16 @@ protected function checkChangedFiles($restartSlaves = true)
10021009
)
10031010
);
10041011

1005-
if ($this->output->isVeryVerbose()) {
1006-
$this->output->writeln(
1007-
sprintf("Changes detection cycle length = %.3f ms", (microtime(true) - $start) * 1000)
1008-
);
1009-
}
1010-
1011-
if ($restartSlaves) {
1012-
$this->restartSlaves();
1013-
}
1012+
$this->restartSlaves();
10141013
}
10151014

1016-
$this->inChangesDetectionCycle = false;
1015+
if ($this->output->isVeryVerbose()) {
1016+
$this->output->writeln(sprintf(
1017+
"Changes detection cycle length = %.3f ms, %u files",
1018+
(microtime(true) - $start) * 1000,
1019+
count($this->filesLastMTime)
1020+
));
1021+
}
10171022

10181023
return $hasChanged;
10191024
}
@@ -1168,16 +1173,14 @@ public function closeSlaves($graceful = false, $onSlaveClosed = null)
11681173
*/
11691174
public function restartSlaves()
11701175
{
1171-
if ($this->inRestart) {
1176+
//Do not restart if we're still starting the slaves
1177+
if ($this->status === self::STATE_STARTING) {
11721178
return;
11731179
}
11741180

1175-
$this->inRestart = true;
1176-
1181+
$this->status = self::STATE_STARTING;
11771182
$this->closeSlaves();
11781183
$this->createSlaves();
1179-
1180-
$this->inRestart = false;
11811184
}
11821185

11831186
/**

0 commit comments

Comments
 (0)