Skip to content

Commit

Permalink
Merge pull request #87 from clue-labs/default-loop
Browse files Browse the repository at this point in the history
Simplify usage by supporting new default loop
  • Loading branch information
clue committed Jul 11, 2021
2 parents 7048601 + efac6d4 commit ca30b94
Show file tree
Hide file tree
Showing 15 changed files with 80 additions and 114 deletions.
58 changes: 27 additions & 31 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,8 @@ as [Streams](https://github.com/reactphp/stream).
## Quickstart example

```php
$loop = React\EventLoop\Factory::create();

$process = new React\ChildProcess\Process('echo foo');
$process->start($loop);
$process->start();

$process->stdout->on('data', function ($chunk) {
echo $chunk;
Expand All @@ -41,8 +39,6 @@ $process->stdout->on('data', function ($chunk) {
$process->on('exit', function($exitCode, $termSignal) {
echo 'Process exited with code ' . $exitCode . PHP_EOL;
});

$loop->run();
```

See also the [examples](examples).
Expand Down Expand Up @@ -80,7 +76,7 @@ you can use any of their events and methods as usual:

```php
$process = new Process($command);
$process->start($loop);
$process->start();

$process->stdout->on('data', function ($chunk) {
echo $chunk;
Expand Down Expand Up @@ -113,7 +109,7 @@ The `Process` class allows you to pass any kind of command line string:

```php
$process = new Process('echo test');
$process->start($loop);
$process->start();
```

The command line string usually consists of a whitespace-separated list with
Expand All @@ -129,7 +125,7 @@ $bin = 'C:\\Program files (x86)\\PHP\\php.exe';
$file = 'C:\\Users\\me\\Desktop\\Application\\main.php';

$process = new Process(escapeshellarg($bin) . ' ' . escapeshellarg($file));
$process->start($loop);
$process->start();
```

By default, PHP will launch processes by wrapping the given command line string
Expand All @@ -146,7 +142,7 @@ streams from the wrapping shell command like this:

```php
$process = new Process('echo run && demo || echo failed');
$process->start($loop);
$process->start();
```

> Note that [Windows support](#windows-compatibility) is limited in that it
Expand All @@ -168,7 +164,7 @@ boundary between each sub-command like this:

```php
$process = new Process('cat first && echo --- && cat second');
$process->start($loop);
$process->start();
```

As an alternative, considering launching one process at a time and listening on
Expand All @@ -177,11 +173,11 @@ This will give you an opportunity to configure the subsequent process I/O stream

```php
$first = new Process('cat first');
$first->start($loop);
$first->start();

$first->on('exit', function () use ($loop) {
$first->on('exit', function () {
$second = new Process('cat second');
$second->start($loop);
$second->start();
});
```

Expand All @@ -191,7 +187,7 @@ also applies to running the most simple single command:

```php
$process = new Process('yes');
$process->start($loop);
$process->start();
```

This will actually spawn a command hierarchy similar to this on Unix:
Expand All @@ -212,7 +208,7 @@ wrapping shell process to be replaced by our process:

```php
$process = new Process('exec yes');
$process->start($loop);
$process->start();
```

This will show a resulting command hierarchy similar to this:
Expand Down Expand Up @@ -244,7 +240,7 @@ arguments:

```php
$process = new Process('sleep 10');
$process->start($loop);
$process->start();

$process->on('exit', function ($code, $term) {
if ($term === null) {
Expand Down Expand Up @@ -292,9 +288,9 @@ accordingly when terminating a process:

```php
$process = new Process('sleep 10');
$process->start($loop);
$process->start();

$loop->addTimer(2.0, function () use ($process) {
Loop::addTimer(2.0, function () use ($process) {
foreach ($process->pipes as $pipe) {
$pipe->close();
}
Expand All @@ -308,9 +304,9 @@ inherited process pipes as [mentioned above](#command).

```php
$process = new Process('exec sleep 10');
$process->start($loop);
$process->start();

$loop->addTimer(2.0, function () use ($process) {
Loop::addTimer(2.0, function () use ($process) {
$process->terminate();
});
```
Expand All @@ -321,9 +317,9 @@ For example, the following can be used to "soft-close" a `cat` process:

```php
$process = new Process('cat');
$process->start($loop);
$process->start();

$loop->addTimer(2.0, function () use ($process) {
Loop::addTimer(2.0, function () use ($process) {
$process->stdin->end();
});
```
Expand Down Expand Up @@ -366,7 +362,7 @@ $fds = array(
);

$process = new Process($cmd, null, null, $fds);
$process->start($loop);
$process->start();
```

Unless your use case has special requirements that demand otherwise, you're
Expand Down Expand Up @@ -429,7 +425,7 @@ instead throw a `LogicException` on Windows by default:
```php
// throws LogicException on Windows
$process = new Process('ping example.com');
$process->start($loop);
$process->start();
```

There are a number of alternatives and workarounds as detailed below if you want
Expand All @@ -449,7 +445,7 @@ to run a child process on Windows, each with its own set of pros and cons:
['socket']
]
);
$process->start($loop);
$process->start();

$process->stdout->on('data', function ($chunk) {
echo $chunk;
Expand All @@ -471,7 +467,7 @@ to run a child process on Windows, each with its own set of pros and cons:

```php
$process = new Process('ping example.com', null, null, array());
$process->start($loop);
$process->start();

$process->on('exit', function ($exitcode) {
echo 'exit with ' . $exitcode . PHP_EOL;
Expand All @@ -494,7 +490,7 @@ to run a child process on Windows, each with its own set of pros and cons:
$stdout = tmpfile(),
array('file', 'nul', 'w')
));
$process->start($loop);
$process->start();

$process->on('exit', function ($exitcode) use ($stdout) {
echo 'exit with ' . $exitcode . PHP_EOL;
Expand All @@ -520,7 +516,7 @@ to run a child process on Windows, each with its own set of pros and cons:
omit any actual standard I/O pipes like this:

```php
$server = new React\Socket\Server('127.0.0.1:0', $loop);
$server = new React\Socket\Server('127.0.0.1:0');
$server->on('connection', function (React\Socket\ConnectionInterface $connection) {
$connection->on('data', function ($chunk) {
echo $chunk;
Expand All @@ -529,7 +525,7 @@ to run a child process on Windows, each with its own set of pros and cons:

$command = 'ping example.com | foobar ' . escapeshellarg($server->getAddress());
$process = new Process($command, null, null, array());
$process->start($loop);
$process->start();

$process->on('exit', function ($exitcode) use ($server) {
$server->close();
Expand Down Expand Up @@ -560,7 +556,7 @@ to run a child process on Windows, each with its own set of pros and cons:
$code = '$s=stream_socket_client($argv[1]);do{fwrite($s,$d=fread(STDIN, 8192));}while(isset($d[0]));';
$command = 'ping example.com | php -r ' . escapeshellarg($code) . ' ' . escapeshellarg($server->getAddress());
$process = new Process($command, null, null, array());
$process->start($loop);
$process->start();
```

See also [example #23](examples/23-forward-socket.php).
Expand All @@ -580,7 +576,7 @@ particular, this means that shell built-in functions such as `echo hello` or

```php
$process = new Process('cmd /c echo hello', null, null, $pipes);
$process->start($loop);
$process->start();
```

## Install
Expand Down
6 changes: 3 additions & 3 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,12 @@
"require": {
"php": ">=5.3.0",
"evenement/evenement": "^3.0 || ^2.0 || ^1.0",
"react/event-loop": "^1.0 || ^0.5 || ^0.4 || ^0.3.5",
"react/stream": "^1.0 || ^0.7.6"
"react/event-loop": "^1.2",
"react/stream": "^1.2"
},
"require-dev": {
"phpunit/phpunit": "^9.3 || ^5.7 || ^4.8.35",
"react/socket": "^1.0",
"react/socket": "^1.8",
"sebastian/environment": "^5.0 || ^3.0 || ^2.0 || ^1.0"
},
"autoload": {
Expand Down
14 changes: 5 additions & 9 deletions examples/01-stdio.php
Original file line number Diff line number Diff line change
@@ -1,18 +1,16 @@
<?php

use React\EventLoop\Factory;
use React\ChildProcess\Process;
use React\EventLoop\Loop;

require __DIR__ . '/../vendor/autoload.php';

if (DIRECTORY_SEPARATOR === '\\') {
exit('Process pipes not supported on Windows' . PHP_EOL);
}

$loop = Factory::create();

$process = new Process('cat');
$process->start($loop);
$process->start();

$process->stdout->on('data', function ($chunk) {
echo $chunk;
Expand All @@ -23,14 +21,12 @@
});

// periodically send something to stream
$periodic = $loop->addPeriodicTimer(0.2, function () use ($process) {
$periodic = Loop::addPeriodicTimer(0.2, function () use ($process) {
$process->stdin->write('hello');
});

// stop sending after a few seconds
$loop->addTimer(2.0, function () use ($periodic, $loop, $process) {
$loop->cancelTimer($periodic);
Loop::addTimer(2.0, function () use ($periodic, $process) {
Loop::cancelTimer($periodic);
$process->stdin->end();
});

$loop->run();
9 changes: 2 additions & 7 deletions examples/02-race.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
<?php

use React\EventLoop\Factory;
use React\ChildProcess\Process;

require __DIR__ . '/../vendor/autoload.php';
Expand All @@ -9,13 +8,11 @@
exit('Process pipes not supported on Windows' . PHP_EOL);
}

$loop = Factory::create();

$first = new Process('sleep 2; echo welt');
$first->start($loop);
$first->start();

$second = new Process('sleep 1; echo hallo');
$second->start($loop);
$second->start();

$first->stdout->on('data', function ($chunk) {
echo $chunk;
Expand All @@ -24,5 +21,3 @@
$second->stdout->on('data', function ($chunk) {
echo $chunk;
});

$loop->run();
7 changes: 1 addition & 6 deletions examples/03-stdout-stderr.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
<?php

use React\EventLoop\Factory;
use React\ChildProcess\Process;

require __DIR__ . '/../vendor/autoload.php';
Expand All @@ -9,10 +8,8 @@
exit('Process pipes not supported on Windows' . PHP_EOL);
}

$loop = Factory::create();

$process = new Process('echo hallo;sleep 1;echo welt >&2;sleep 1;echo error;sleep 1;nope');
$process->start($loop);
$process->start();

$process->stdout->on('data', function ($chunk) {
echo '(' . $chunk . ')';
Expand All @@ -25,5 +22,3 @@
$process->on('exit', function ($code) {
echo 'EXIT with code ' . $code . PHP_EOL;
});

$loop->run();
10 changes: 3 additions & 7 deletions examples/04-terminate.php
Original file line number Diff line number Diff line change
@@ -1,27 +1,23 @@
<?php

use React\EventLoop\Factory;
use React\ChildProcess\Process;
use React\EventLoop\Loop;

require __DIR__ . '/../vendor/autoload.php';

$loop = Factory::create();

// start a process that takes 10s to terminate
$process = new Process('php -r "sleep(10);"', null, null, array());
$process->start($loop);
$process->start();

// report when process exits
$process->on('exit', function ($exit, $term) {
var_dump($exit, $term);
});

// forcefully terminate process after 2s
$loop->addTimer(2.0, function () use ($process) {
Loop::addTimer(2.0, function () use ($process) {
foreach ($process->pipes as $pipe) {
$pipe->close();
}
$process->terminate();
});

$loop->run();
7 changes: 1 addition & 6 deletions examples/05-stdio-sockets.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
<?php

use React\EventLoop\Factory;
use React\ChildProcess\Process;

require __DIR__ . '/../vendor/autoload.php';
Expand All @@ -9,8 +8,6 @@
exit('Socket descriptors require PHP 8+' . PHP_EOL);
}

$loop = Factory::create();

$process = new Process(
'php -r ' . escapeshellarg('echo 1;sleep(1);fwrite(STDERR,2);exit(3);'),
null,
Expand All @@ -21,7 +18,7 @@
['socket']
]
);
$process->start($loop);
$process->start();

$process->stdout->on('data', function ($chunk) {
echo '(' . $chunk . ')';
Expand All @@ -34,5 +31,3 @@
$process->on('exit', function ($code) {
echo 'EXIT with code ' . $code . PHP_EOL;
});

$loop->run();

0 comments on commit ca30b94

Please sign in to comment.