Skip to content

Commit 4b8a58d

Browse files
committed
feat: add ProcTasks for run task by php multi process
1 parent acc9af5 commit 4b8a58d

File tree

10 files changed

+829
-276
lines changed

10 files changed

+829
-276
lines changed

README.md

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,61 @@ Some useful system utils for php
1717
composer require toolkit/sys-utils
1818
```
1919

20+
## Usage
21+
22+
### ProcTasks
23+
24+
**Example**:
25+
26+
```php
27+
use Toolkit\Sys\Proc\ProcTasks;
28+
29+
// ProcTasks::new() // will auto get cpu num as proc num
30+
ProcTasks::new(['procNum' => 2])
31+
->setTaskHandler(function (array $task, array $ctx) {
32+
$pid = $ctx['pid'];
33+
println("worker#{$ctx['id']} [PID:$pid] - handle task, task data", $task);
34+
sleep(random_int(1, 3));
35+
})
36+
->onBeforeCreate(fn($pid, $num) => println("master [PID:$pid] - Will create task process, number:", $num))
37+
->onWorkersCreated(fn($pid, $info) => println("master [PID:$pid] - All task process started,", 'Workers info', $info))
38+
->onWorkerStart(fn($pid, $id) => println("worker#$id started, pid is", $pid))
39+
->onWorkerExit(fn($pid, $id) => println("worker#$id exited, pid is", $pid))
40+
->onWorkersExited(fn($pid) => println("master [PID:$pid] - all workers exited, tasks run completed"))
41+
->setTasks([
42+
['task1'], // one task
43+
['task2'],
44+
['task3'],
45+
['task4'],
46+
])
47+
->addTask(['task5'])
48+
->run();
49+
```
50+
51+
**Run**:
52+
53+
```bash
54+
php example/proc-tasks.php
55+
```
56+
57+
**Output**:
58+
59+
```text
60+
master [PID:49731] - Will create task process, number: 2
61+
master [PID:49731] - All task process started, Workers info {"49732":{"id":0,"pid":49732,"startAt":1639245860},"49733":{"id":1,"pid":49733,"startAt":1639245860}}
62+
worker#0 started, pid is 49732
63+
worker#0 [PID:49732] - handle task, task data ["task1"]
64+
worker#1 started, pid is 49733
65+
worker#1 [PID:49733] - handle task, task data ["task4"]
66+
worker#1 [PID:49733] - handle task, task data ["task5"]
67+
worker#0 [PID:49732] - handle task, task data ["task2"]
68+
worker#1 exited, pid is 49733
69+
worker#0 [PID:49732] - handle task, task data ["task3"]
70+
worker#0 exited, pid is 49732
71+
master [PID:49731] - all workers exited, tasks run completed
72+
73+
```
74+
2075
## License
2176

2277
[MIT](LICENSE)

example/proc-editor.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@
77
* @license MIT
88
*/
99

10+
use Toolkit\Sys\Proc\ProcWrapper;
11+
1012
require dirname(__DIR__) . '/test/bootstrap.php';
1113

1214
$editor = 'vim';
13-
Toolkit\Sys\Proc\ProcWrapper::runEditor($editor, 'test.txt');
15+
ProcWrapper::runEditor($editor, 'test.txt');

example/proc-tasks.php

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<?php declare(strict_types=1);
2+
3+
use Toolkit\Sys\Proc\ProcTasks;
4+
5+
require dirname(__DIR__) . '/test/bootstrap.php';
6+
7+
// run: php example/proc-tasks.php
8+
// ProcTasks::new() // will auto get cpu num as proc num
9+
ProcTasks::new(['procNum' => 3])
10+
->setTaskHandler(function (array $task, array $ctx) {
11+
$pid = $ctx['pid'];
12+
println("worker#{$ctx['id']} [PID:$pid] - handle task, task data", $task);
13+
sleep(random_int(1, 3));
14+
})
15+
->onBeforeCreate(fn($pid, $num) => println("master [PID:$pid] - Will create task process, number:", $num))
16+
->onWorkersCreated(fn($pid, $info) => println("master [PID:$pid] - All task process started,", 'Workers info', $info))
17+
->onWorkerStart(fn($pid, $id) => println("worker#$id started, pid is", $pid))
18+
->onWorkerExit(fn($pid, $id) => println("worker#$id exited, pid is", $pid))
19+
->onWorkersExited(fn($pid) => println("master [PID:$pid] - all workers exited, tasks run completed"))
20+
->setTasks([
21+
['task1'], // one task
22+
['task2'],
23+
['task3'],
24+
['task4'],
25+
])
26+
->addTask(['task5'])
27+
->run();

example/proc0.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,15 @@
77
* @license MIT
88
*/
99

10+
use Toolkit\Sys\Proc\ProcWrap;
11+
1012
require dirname(__DIR__) . '/test/bootstrap.php';
13+
14+
// run: php example/proc0.php
15+
$proc = ProcWrap::new('ls -al')->run();
16+
17+
vdump($proc->getStatus());
18+
19+
$proc->closeAll();
20+
21+
// vdump($proc->getStatus()); // will ex

src/Exec.php

Lines changed: 70 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
use function pclose;
2222
use function popen;
2323
use function shell_exec;
24+
use function stream_get_contents;
2425
use function system;
2526
use function trim;
2627

@@ -36,19 +37,71 @@ class Exec
3637
* @param string $workDir
3738
* @param bool $outAsString
3839
*
39-
* @return array
40+
* @return array{int, string|array}
4041
*/
4142
public static function exec(string $command, string $workDir = '', bool $outAsString = true): array
4243
{
44+
$curDir = '';
4345
if ($workDir) {
46+
$curDir = getcwd();
4447
chdir($workDir);
4548
}
4649

4750
exec($command, $output, $status);
4851

52+
// fix: revert workdir after run end.
53+
if ($curDir) {
54+
chdir($curDir);
55+
}
56+
4957
return [$status, $outAsString ? implode("\n", $output) : $output];
5058
}
5159

60+
/**
61+
* Exec an command and get output. use popen()
62+
*
63+
* @param string $command
64+
* @param string $workDir
65+
*
66+
* @return string
67+
*/
68+
public static function pexec(string $command, string $workDir = ''): string
69+
{
70+
$output = $curDir = '';
71+
if ($workDir) {
72+
$curDir = getcwd();
73+
chdir($workDir);
74+
}
75+
76+
// popen
77+
$proc = popen($command, 'rb');
78+
if (false !== $proc) {
79+
$output = stream_get_contents($proc);
80+
pclose($proc);
81+
}
82+
83+
// fix: revert workdir after run end.
84+
if ($curDir) {
85+
chdir($curDir);
86+
}
87+
88+
return $output;
89+
}
90+
91+
/**
92+
* run a command. it is support windows
93+
*
94+
* @param string $command
95+
* @param string $cwd
96+
*
97+
* @return array [$code, $output, $error]
98+
* @throws RuntimeException
99+
*/
100+
public static function run(string $command, string $cwd = ''): array
101+
{
102+
return ProcWrapper::runCmd($command, $cwd);
103+
}
104+
52105
/**
53106
* @param string $command
54107
* @param string $workDir
@@ -129,17 +182,16 @@ public static function inBackground(string $cmd): void
129182
}
130183

131184
/**
132-
* run a command. it is support windows
185+
* Quick exec an command and return output
133186
*
134187
* @param string $command
135188
* @param string $cwd
136189
*
137-
* @return array [$code, $output, $error]
138-
* @throws RuntimeException
190+
* @return string
139191
*/
140-
public static function run(string $command, string $cwd = ''): array
192+
public static function getOutput(string $command, string $cwd = ''): string
141193
{
142-
return ProcWrapper::runCmd($command, $cwd);
194+
return self::auto($command, false, $cwd);
143195
}
144196

145197
/**
@@ -171,17 +223,25 @@ public static function auto(string $command, bool $returnStatus = true, string $
171223
ob_start();
172224
system($command, $status);
173225
$output = ob_get_clean();
174-
//exec
226+
227+
// exec
175228
} elseif (function_exists('exec')) {
176229
exec($command, $output, $status);
177230
$output = implode("\n", $output);
178231

179-
//shell_exec
232+
// shell_exec
180233
} elseif (function_exists('shell_exec')) {
181234
$output = shell_exec($command);
182235
} else {
183-
$status = -1;
184-
$output = 'Command execution not possible on this system';
236+
// popen
237+
$proc = popen($command, 'rb');
238+
if (false !== $proc) {
239+
$status = 0;
240+
$output = stream_get_contents($proc);
241+
} else {
242+
$status = -1;
243+
$output = 'Command execution not possible on this system';
244+
}
185245
}
186246

187247
// fix: revert workdir after run end.
@@ -195,7 +255,6 @@ public static function auto(string $command, bool $returnStatus = true, string $
195255
'status' => $status
196256
];
197257
}
198-
199258
return trim($output);
200259
}
201260

@@ -227,17 +286,4 @@ public static function execWithSudo(string $command, string $logfile = '', strin
227286

228287
return $dummy;
229288
}
230-
231-
/**
232-
* Quick exec an command and return output
233-
*
234-
* @param string $command
235-
* @param string $cwd
236-
*
237-
* @return string
238-
*/
239-
public static function getOutput(string $command, string $cwd = ''): string
240-
{
241-
return self::auto($command, false, $cwd);
242-
}
243289
}

0 commit comments

Comments
 (0)