17
17
use Symfony \Component \Process \Process ;
18
18
use Webmozart \Assert \Assert ;
19
19
use Webmozarts \Console \Parallelization \Logger \Logger ;
20
+ use function count ;
21
+ use function sprintf ;
22
+ use const PHP_EOL ;
20
23
21
24
/**
22
25
* Launches a number of processes and distributes data among these processes.
25
28
* processes as configured in the constructor. Each process receives a share
26
29
* of the data set via its standard input, separated by newlines. The size
27
30
* of this share can be configured in the constructor (the segment size).
31
+ *
32
+ * @phpstan-import-type ProcessOutput from ProcessLauncherFactory
28
33
*/
29
34
final class SymfonyProcessLauncher implements ProcessLauncher
30
35
{
@@ -53,12 +58,12 @@ final class SymfonyProcessLauncher implements ProcessLauncher
53
58
private Logger $ logger ;
54
59
55
60
/**
56
- * @var callable(string, string): void
61
+ * @var ProcessOutput
57
62
*/
58
- private $ callback ;
63
+ private $ processOutput ;
59
64
60
65
/**
61
- * @var Process[]
66
+ * @var array<positive-int|0, Process>
62
67
*/
63
68
private array $ runningProcesses = [];
64
69
@@ -70,12 +75,14 @@ final class SymfonyProcessLauncher implements ProcessLauncher
70
75
private SymfonyProcessFactory $ processFactory ;
71
76
72
77
/**
73
- * @param list<string> $command
74
- * @param array<string, string>|null $extraEnvironmentVariables
75
- * @param positive-int $numberOfProcesses
76
- * @param positive-int $segmentSize
77
- * @param callable(string, string): void $callback
78
- * @param callable(): void $tick
78
+ * @param list<string> $command
79
+ * @param array<string, string>|null $extraEnvironmentVariables
80
+ * @param positive-int $numberOfProcesses
81
+ * @param positive-int $segmentSize
82
+ * @param ProcessOutput $processOutput A PHP callback which is run whenever
83
+ * there is some output available on
84
+ * STDOUT or STDERR.
85
+ * @param callable(): void $tick
79
86
*/
80
87
public function __construct (
81
88
array $ command ,
@@ -84,7 +91,7 @@ public function __construct(
84
91
int $ numberOfProcesses ,
85
92
int $ segmentSize ,
86
93
Logger $ logger ,
87
- callable $ callback ,
94
+ callable $ processOutput ,
88
95
callable $ tick ,
89
96
SymfonyProcessFactory $ processFactory
90
97
) {
@@ -94,7 +101,7 @@ public function __construct(
94
101
$ this ->numberOfProcesses = $ numberOfProcesses ;
95
102
$ this ->segmentSize = $ segmentSize ;
96
103
$ this ->logger = $ logger ;
97
- $ this ->callback = $ callback ;
104
+ $ this ->processOutput = $ processOutput ;
98
105
$ this ->tick = $ tick ;
99
106
$ this ->processFactory = $ processFactory ;
100
107
}
@@ -155,15 +162,31 @@ public function run(iterable $items): int
155
162
156
163
private function startProcess (InputStream $ inputStream ): void
157
164
{
165
+ $ index = count ($ this ->runningProcesses );
166
+
158
167
$ process = $ this ->processFactory ->startProcess (
168
+ $ index ,
159
169
$ inputStream ,
160
170
$ this ->command ,
161
171
$ this ->workingDirectory ,
162
172
$ this ->environmentVariables ,
163
- $ this ->callback ,
173
+ $ this ->processOutput ,
174
+ );
175
+
176
+ $ pid = $ process ->getPid ();
177
+ Assert::notNull (
178
+ $ pid ,
179
+ sprintf (
180
+ 'Expected the process #%d to have a PID. None found. ' ,
181
+ $ index ,
182
+ ),
164
183
);
165
184
166
- $ this ->logger ->logChildProcessStarted ($ process ->getCommandLine ());
185
+ $ this ->logger ->logChildProcessStarted (
186
+ $ index ,
187
+ $ pid ,
188
+ $ process ->getCommandLine (),
189
+ );
167
190
168
191
$ this ->runningProcesses [] = $ process ;
169
192
}
@@ -188,11 +211,13 @@ private function freeTerminatedProcesses(): int
188
211
}
189
212
190
213
/**
191
- * @return 0|positive-int
214
+ * @param positive-int|0 $index
215
+ *
216
+ * @return positive-int|0
192
217
*/
193
218
private function freeProcess (int $ index , Process $ process ): int
194
219
{
195
- $ this ->logger ->logChildProcessFinished ();
220
+ $ this ->logger ->logChildProcessFinished ($ index );
196
221
197
222
unset($ this ->runningProcesses [$ index ]);
198
223
@@ -219,7 +244,10 @@ private static function getExitCode(Process $process): int
219
244
}
220
245
// @codeCoverageIgnoreEnd
221
246
222
- Assert::natural ($ exitCode , 'Expected the process to be finished and return a valid exit code. ' );
247
+ Assert::notNull (
248
+ $ exitCode ,
249
+ 'Expected the process to have an exit code. Got "null" instead. ' ,
250
+ );
223
251
224
252
return $ exitCode ;
225
253
}
0 commit comments