Skip to content

Commit 35f117e

Browse files
committed
Filesystem watcher refactoring
Don't use child process for resource watcher.
1 parent f297324 commit 35f117e

9 files changed

+66
-77
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
## 0.6.0 (2020-05-11)
2+
* Fix: don't use child process for resource watching
3+
14
## 0.5.2 (2019-12-07)
25
* Fix: use predefined const for PHP binary [#59](https://github.com/seregazhuk/php-watcher/pull/59)
36
* Fix: increase dependency options [#58](https://github.com/seregazhuk/php-watcher/pull/58) by @mmoreram

src/Filesystem/ChangesListener.php

Lines changed: 12 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -10,41 +10,26 @@
1010

1111
final class ChangesListener extends EventEmitter
1212
{
13-
private const WATCHER_SCRIPT = '/watcher.php';
13+
private const INTERVAL = 0.15;
1414

1515
private $loop;
1616

17-
private $watchList;
18-
19-
public function __construct(LoopInterface $loop, WatchList $watchList)
17+
public function __construct(LoopInterface $loop)
2018
{
2119
$this->loop = $loop;
22-
$this->watchList = $watchList;
23-
}
24-
25-
public function start(): void
26-
{
27-
$watcherProcess = new Process($this->scriptToRun());
28-
$watcherProcess->start($this->loop);
29-
30-
$this->handleOutput($watcherProcess);
3120
}
3221

33-
private function handleOutput(Process $process): void
22+
public function start(WatchList $watchList): void
3423
{
35-
if ($process->stdout === null) {
36-
throw new RuntimeException('Cannot open STDOUT for filesystem watcher');
37-
}
38-
39-
$process->stdout->on('data', function (string $data) {
40-
if ((bool)$data) {
41-
$this->emit('change');
24+
$watcher = ResourceWatcherBuilder::create($watchList);
25+
26+
$this->loop->addPeriodicTimer(
27+
self::INTERVAL,
28+
function () use ($watcher) {
29+
if ($watcher->findChanges()->hasChanges()) {
30+
$this->emit('change');
31+
}
4232
}
43-
});
44-
}
45-
46-
private function scriptToRun(): string
47-
{
48-
return sprintf('exec php %s "%s"', __DIR__ . self::WATCHER_SCRIPT, addslashes($this->watchList->toJson()));
33+
);
4934
}
5035
}

src/Filesystem/ResourceWatcherFactory.php renamed to src/Filesystem/ResourceWatcherBuilder.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
use Yosymfony\ResourceWatcher\ResourceCacheMemory;
99
use Yosymfony\ResourceWatcher\ResourceWatcher;
1010

11-
final class ResourceWatcherFactory
11+
final class ResourceWatcherBuilder
1212
{
1313
public static function create(WatchList $watchList): ResourceWatcher
1414
{

src/Filesystem/watcher.php

Lines changed: 0 additions & 32 deletions
This file was deleted.

src/Watcher.php

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1-
<?php declare(strict_types=1);
1+
<?php
2+
declare(strict_types=1);
23

34
namespace seregazhuk\PhpWatcher;
45

56
use React\EventLoop\LoopInterface;
7+
use seregazhuk\PhpWatcher\Config\WatchList;
68
use seregazhuk\PhpWatcher\Filesystem\ChangesListener;
79

810
final class Watcher
@@ -17,15 +19,22 @@ public function __construct(LoopInterface $loop, ChangesListener $filesystemList
1719
$this->filesystemListener = $filesystemListener;
1820
}
1921

20-
public function startWatching(ProcessRunner $processRunner, int $signal, float $delayToRestart): void
21-
{
22+
public function startWatching(
23+
ProcessRunner $processRunner,
24+
WatchList $watchList,
25+
int $signal,
26+
float $delayToRestart
27+
): void {
2228
$processRunner->start();
2329

24-
$this->filesystemListener->start();
25-
$this->filesystemListener->on('change', static function () use ($processRunner, $signal, $delayToRestart) {
26-
$processRunner->stop($signal);
27-
$processRunner->restart($delayToRestart);
28-
});
30+
$this->filesystemListener->start($watchList);
31+
$this->filesystemListener->on(
32+
'change',
33+
static function () use ($processRunner, $signal, $delayToRestart) {
34+
$processRunner->stop($signal);
35+
$processRunner->restart($delayToRestart);
36+
}
37+
);
2938

3039
$this->loop->run();
3140
}

src/WatcherCommand.php

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
<?php declare(strict_types=1);
1+
<?php
2+
declare(strict_types=1);
23

34
namespace seregazhuk\PhpWatcher;
45

@@ -25,13 +26,30 @@ protected function configure(): void
2526
$this->setName('watch')
2627
->setDescription('Restart PHP application once the source code changes.')
2728
->addArgument('script', InputArgument::REQUIRED, 'Script to run')
28-
->addOption('watch', '-w', InputOption::VALUE_IS_ARRAY + InputOption::VALUE_OPTIONAL, 'Paths to watch')
29+
->addOption(
30+
'watch',
31+
'-w',
32+
InputOption::VALUE_IS_ARRAY + InputOption::VALUE_OPTIONAL,
33+
'Paths to watch'
34+
)
2935
->addOption('ext', '-e', InputOption::VALUE_OPTIONAL, 'Extensions to watch', '')
30-
->addOption('ignore', '-i', InputOption::VALUE_IS_ARRAY + InputOption::VALUE_OPTIONAL, 'Paths to ignore', [])
36+
->addOption(
37+
'ignore',
38+
'-i',
39+
InputOption::VALUE_IS_ARRAY + InputOption::VALUE_OPTIONAL,
40+
'Paths to ignore',
41+
[]
42+
)
3143
->addOption('exec', null, InputOption::VALUE_OPTIONAL, 'PHP executable')
3244
->addOption('delay', null, InputOption::VALUE_OPTIONAL, 'Delaying restart')
3345
->addOption('signal', null, InputOption::VALUE_OPTIONAL, 'Signal to reload the app')
34-
->addOption('arguments', null, InputOption::VALUE_IS_ARRAY + InputOption::VALUE_OPTIONAL, 'Arguments for the script', [])
46+
->addOption(
47+
'arguments',
48+
null,
49+
InputOption::VALUE_IS_ARRAY + InputOption::VALUE_OPTIONAL,
50+
'Arguments for the script',
51+
[]
52+
)
3553
->addOption('config', null, InputOption::VALUE_OPTIONAL, 'Path to config file')
3654
->addOption('no-spinner', null, InputOption::VALUE_NONE, 'Remove spinner from output');
3755
}
@@ -45,13 +63,18 @@ protected function execute(InputInterface $input, OutputInterface $output)
4563
$this->addTerminationListeners($loop, $spinner);
4664

4765
$screen = new Screen(new SymfonyStyle($input, $output), $spinner);
48-
$filesystem = new ChangesListener($loop, $config->watchList());
66+
$filesystem = new ChangesListener($loop);
4967

5068
$screen->showOptions($config->watchList());
5169
$processRunner = new ProcessRunner($loop, $screen, $config->command());
5270

5371
$watcher = new Watcher($loop, $filesystem);
54-
$watcher->startWatching($processRunner, $config->signalToReload(), $config->delay());
72+
$watcher->startWatching(
73+
$processRunner,
74+
$config->watchList(),
75+
$config->signalToReload(),
76+
$config->delay()
77+
);
5578

5679
return 0;
5780
}

tests/Feature/ChangesListenerTest.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ final class ChangesListenerTest extends TestCase
1818
public function it_emits_change_event_on_changes(): void
1919
{
2020
$loop = Factory::create();
21-
$listener = new ChangesListener($loop, new WatchList([Filesystem::fixturesDir()]));
22-
$listener->start();
21+
$listener = new ChangesListener($loop);
22+
$listener->start(new WatchList([Filesystem::fixturesDir()]));
2323

2424
$loop->addTimer(1, [Filesystem::class, 'createHelloWorldPHPFile']);
2525
$eventWasEmitted = false;

tests/Feature/Helper/WatcherTestCase.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ abstract class WatcherTestCase extends TestCase
99
{
1010
use WithFilesystem;
1111

12-
private const WAIT_TIMEOUT_MS = 2500000;
12+
private const WAIT_TIMEOUT_MS = 5000000;
1313

1414
/**
1515
* @var Process

tests/Feature/WatchDirectoriesTest.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ public function it_reloads_by_changes_in_a_watched_dir(): void
2828

2929
Filesystem::changeFileContentsWith($fileToWatch, '<?php echo "Something changed"; ');
3030
$this->wait();
31+
3132
$this->assertOutputContains('restarting due to changes...');
3233
}
3334
}

0 commit comments

Comments
 (0)