Skip to content

Commit f72aca3

Browse files
committed
Detect exit immediately if last process pipe is closed
1 parent 56c7db4 commit f72aca3

2 files changed

Lines changed: 44 additions & 1 deletion

File tree

src/Process.php

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,10 +115,18 @@ public function start(LoopInterface $loop, $interval = 0.1)
115115
return;
116116
}
117117

118+
// process already closed => report immediately
119+
if (!$that->isRunning()) {
120+
$that->close();
121+
$that->emit('exit', array($that->getExitCode(), $that->getTermSignal()));
122+
return;
123+
}
124+
125+
// close not detected immediately => check regularly
118126
$loop->addPeriodicTimer($interval, function ($timer) use ($that, $loop) {
119127
if (!$that->isRunning()) {
120-
$that->close();
121128
$loop->cancelTimer($timer);
129+
$that->close();
122130
$that->emit('exit', array($that->getExitCode(), $that->getTermSignal()));
123131
}
124132
});

tests/AbstractProcessTest.php

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,41 @@ public function testStartAndAllowProcessToExitSuccessfullyUsingEventLoop()
243243
$this->assertFalse($process->isTerminated());
244244
}
245245

246+
public function testProcessWillExitFasterThanExitInterval()
247+
{
248+
$loop = $this->createLoop();
249+
$process = new Process('echo hi');
250+
$process->start($loop, 2);
251+
252+
$time = microtime(true);
253+
$loop->run();
254+
$time = microtime(true) - $time;
255+
256+
$this->assertLessThan(0.1, $time);
257+
}
258+
259+
public function testDetectsClosingStdoutWithoutHavingToWaitForExit()
260+
{
261+
$cmd = 'exec ' . $this->getPhpBinary() . ' -r ' . escapeshellarg('fclose(STDOUT); sleep(1);');
262+
263+
$loop = $this->createLoop();
264+
$process = new Process($cmd);
265+
$process->start($loop);
266+
267+
$closed = false;
268+
$process->stdout->on('close', function () use (&$closed) {
269+
$closed = true;
270+
});
271+
272+
// run loop for 0.1s only
273+
$loop->addTimer(0.1, function () use ($loop) {
274+
$loop->stop();
275+
});
276+
$loop->run();
277+
278+
$this->assertTrue($closed);
279+
}
280+
246281
public function testStartInvalidProcess()
247282
{
248283
$cmd = tempnam(sys_get_temp_dir(), 'react');

0 commit comments

Comments
 (0)