mirror of
https://github.com/danog/parallel.git
synced 2025-01-22 14:01:14 +01:00
Fix some bugs, clean up, and update doc blocks
This commit is contained in:
parent
9dc54a9b47
commit
ed73b1dd7b
@ -146,12 +146,14 @@ class Process implements ProcessContext {
|
|||||||
|
|
||||||
$this->pid = $status["pid"];
|
$this->pid = $status["pid"];
|
||||||
|
|
||||||
|
foreach ($pipes as $pipe) {
|
||||||
|
\stream_set_blocking($pipe, false);
|
||||||
|
}
|
||||||
|
|
||||||
$this->stdin = $stdin = $pipes[0];
|
$this->stdin = $stdin = $pipes[0];
|
||||||
$this->stdout = $pipes[1];
|
$this->stdout = $pipes[1];
|
||||||
$this->stderr = $pipes[2];
|
$this->stderr = $pipes[2];
|
||||||
|
|
||||||
$stream = $pipes[3];
|
$stream = $pipes[3];
|
||||||
\stream_set_blocking($stream, false);
|
|
||||||
|
|
||||||
$process = &$this->process;
|
$process = &$this->process;
|
||||||
|
|
||||||
|
@ -12,10 +12,10 @@ class StreamedProcess implements ProcessContext {
|
|||||||
/** @var \Amp\Parallel\Process\Process */
|
/** @var \Amp\Parallel\Process\Process */
|
||||||
private $process;
|
private $process;
|
||||||
|
|
||||||
/** @var \Amp\Emitter|null */
|
/** @var \Amp\Emitter Emits bytes read from STDOUT. */
|
||||||
private $stdoutEmitter;
|
private $stdoutEmitter;
|
||||||
|
|
||||||
/** @var \Amp\Emitter|null */
|
/** @var \Amp\Emitter Emits bytes read from STDERR. */
|
||||||
private $stderrEmitter;
|
private $stderrEmitter;
|
||||||
|
|
||||||
/** @var string|null */
|
/** @var string|null */
|
||||||
@ -27,9 +27,10 @@ class StreamedProcess implements ProcessContext {
|
|||||||
/** @var string|null */
|
/** @var string|null */
|
||||||
private $stderrWatcher;
|
private $stderrWatcher;
|
||||||
|
|
||||||
/** @var \SplQueue|null */
|
/** @var \SplQueue Queue of data to write to STDIN. */
|
||||||
private $writeQueue;
|
private $writeQueue;
|
||||||
|
|
||||||
|
/** @var \AsyncInterop\Promise Promise resolved when process ends. */
|
||||||
private $promise;
|
private $promise;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -43,21 +44,7 @@ class StreamedProcess implements ProcessContext {
|
|||||||
$this->process = new Process($command, $cwd, $env, $options);
|
$this->process = new Process($command, $cwd, $env, $options);
|
||||||
$this->stdoutEmitter = new Emitter;
|
$this->stdoutEmitter = new Emitter;
|
||||||
$this->stderrEmitter = new Emitter;
|
$this->stderrEmitter = new Emitter;
|
||||||
}
|
$this->writeQueue = new \SplQueue;
|
||||||
|
|
||||||
|
|
||||||
public function __destruct() {
|
|
||||||
if ($this->stdinWatcher) {
|
|
||||||
Loop::cancel($this->stdinWatcher);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($this->stdoutWatcher) {
|
|
||||||
Loop::cancel($this->stdoutWatcher);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($this->stderrWatcher) {
|
|
||||||
Loop::cancel($this->stderrWatcher);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -70,6 +57,8 @@ class StreamedProcess implements ProcessContext {
|
|||||||
$this->stderrWatcher = null;
|
$this->stderrWatcher = null;
|
||||||
$this->stdoutEmitter = new Emitter;
|
$this->stdoutEmitter = new Emitter;
|
||||||
$this->stderrEmitter = new Emitter;
|
$this->stderrEmitter = new Emitter;
|
||||||
|
$this->writeQueue = new \SplQueue;
|
||||||
|
$this->promise = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -78,7 +67,7 @@ class StreamedProcess implements ProcessContext {
|
|||||||
public function start() {
|
public function start() {
|
||||||
$this->process->start();
|
$this->process->start();
|
||||||
|
|
||||||
$this->writeQueue = $writes = new \SplQueue;
|
$writes = $this->writeQueue;
|
||||||
$this->stdinWatcher = Loop::onWritable($this->process->getStdIn(), static function ($watcher, $resource) use ($writes) {
|
$this->stdinWatcher = Loop::onWritable($this->process->getStdIn(), static function ($watcher, $resource) use ($writes) {
|
||||||
while (!$writes->isEmpty()) {
|
while (!$writes->isEmpty()) {
|
||||||
/** @var \Amp\Deferred $deferred */
|
/** @var \Amp\Deferred $deferred */
|
||||||
@ -114,56 +103,35 @@ class StreamedProcess implements ProcessContext {
|
|||||||
});
|
});
|
||||||
Loop::disable($this->stdinWatcher);
|
Loop::disable($this->stdinWatcher);
|
||||||
|
|
||||||
$stdout = &$this->stdoutEmitter;
|
$callback = static function ($watcher, $resource, Emitter $emitter) {
|
||||||
$this->stdoutWatcher = Loop::onReadable($this->process->getStdOut(), static function ($watcher, $resource) use (&$stdout) {
|
|
||||||
if (@\feof($resource)) {
|
|
||||||
Loop::cancel($watcher);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Error reporting suppressed since fread() produces a warning if the stream unexpectedly closes.
|
// Error reporting suppressed since fread() produces a warning if the stream unexpectedly closes.
|
||||||
$data = @\fread($resource, self::CHUNK_SIZE);
|
if (@\feof($resource) || ($data = @\fread($resource, self::CHUNK_SIZE)) === false) {
|
||||||
|
Loop::disable($watcher);
|
||||||
if ($data === false) {
|
|
||||||
Loop::cancel($watcher);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($data !== "") {
|
if ($data !== "") {
|
||||||
$stdout->emit($data);
|
$emitter->emit($data);
|
||||||
}
|
}
|
||||||
});
|
};
|
||||||
|
|
||||||
$stderr = &$this->stderrEmitter;
|
$this->stdoutWatcher = Loop::onReadable($this->process->getStdOut(), $callback, $this->stdoutEmitter);
|
||||||
$this->stderrWatcher = Loop::onReadable($this->process->getStdErr(), static function ($watcher, $resource) use (&$stderr) {
|
$this->stderrWatcher = Loop::onReadable($this->process->getStdErr(), $callback, $this->stderrEmitter);
|
||||||
if (@\feof($resource)) {
|
|
||||||
Loop::cancel($watcher);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Error reporting suppressed since fread() produces a warning if the stream unexpectedly closes.
|
|
||||||
$data = @\fread($resource, self::CHUNK_SIZE);
|
|
||||||
|
|
||||||
if ($data === false) {
|
|
||||||
Loop::cancel($watcher);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($data !== "") {
|
|
||||||
$stderr->emit($data);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
$this->promise = $this->process->join();
|
$this->promise = $this->process->join();
|
||||||
$this->promise->when(static function (\Throwable $exception = null, int $code = null) use (&$stdout, &$stderr) {
|
$this->promise->when(function (\Throwable $exception = null, int $code = null) {
|
||||||
|
Loop::cancel($this->stdinWatcher);
|
||||||
|
Loop::cancel($this->stdoutWatcher);
|
||||||
|
Loop::cancel($this->stderrWatcher);
|
||||||
|
|
||||||
if ($exception) {
|
if ($exception) {
|
||||||
$stdout->fail($exception);
|
$this->stdoutEmitter->fail($exception);
|
||||||
$stderr->fail($exception);
|
$this->stderrEmitter->fail($exception);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$stdout->resolve($code);
|
$this->stdoutEmitter->resolve($code);
|
||||||
$stderr->resolve($code);
|
$this->stderrEmitter->resolve($code);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -230,18 +198,10 @@ class StreamedProcess implements ProcessContext {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function getStdOut(): Stream {
|
public function getStdOut(): Stream {
|
||||||
if ($this->stdoutEmitter === null) {
|
|
||||||
throw new StatusError("The process has not been started");
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->stdoutEmitter->stream();
|
return $this->stdoutEmitter->stream();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getStdErr(): Stream {
|
public function getStdErr(): Stream {
|
||||||
if ($this->stderrEmitter === null) {
|
|
||||||
throw new StatusError("The process has not been started");
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->stderrEmitter->stream();
|
return $this->stderrEmitter->stream();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -249,6 +209,10 @@ class StreamedProcess implements ProcessContext {
|
|||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
public function join(): Promise {
|
public function join(): Promise {
|
||||||
|
if ($this->promise === null) {
|
||||||
|
throw new StatusError("The process has not been started");
|
||||||
|
}
|
||||||
|
|
||||||
return $this->promise;
|
return $this->promise;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user