10
10
use Magento \Deploy \Package \Package ;
11
11
use Magento \Deploy \Service \DeployPackage ;
12
12
use Magento \Framework \App \ResourceConnection ;
13
- use Psr \Log \LoggerInterface ;
14
13
use Magento \Framework \App \State as AppState ;
15
14
use Magento \Framework \Locale \ResolverInterface as LocaleResolver ;
15
+ use Psr \Log \LoggerInterface ;
16
16
17
17
/**
18
18
* Deployment Queue
@@ -165,6 +165,7 @@ public function process()
165
165
$ packages = $ this ->packages ;
166
166
while (count ($ packages ) && $ this ->checkTimeout ()) {
167
167
foreach ($ packages as $ name => $ packageJob ) {
168
+ // Unsets each member of $packages array (passed by reference) as each is executed
168
169
$ this ->assertAndExecute ($ name , $ packages , $ packageJob );
169
170
}
170
171
$ this ->logger ->info ('. ' );
@@ -224,12 +225,8 @@ private function assertAndExecute($name, array & $packages, array $packageJob)
224
225
* @param bool $dependenciesNotFinished
225
226
* @return void
226
227
*/
227
- private function executePackage (
228
- Package $ package ,
229
- string $ name ,
230
- array &$ packages ,
231
- bool $ dependenciesNotFinished
232
- ) {
228
+ private function executePackage (Package $ package , string $ name , array &$ packages , bool $ dependenciesNotFinished )
229
+ {
233
230
if (!$ dependenciesNotFinished
234
231
&& !$ this ->isDeployed ($ package )
235
232
&& ($ this ->maxProcesses < 2 || (count ($ this ->inProgress ) < $ this ->maxProcesses ))
@@ -338,14 +335,41 @@ private function isDeployed(Package $package)
338
335
{
339
336
if ($ this ->isCanBeParalleled ()) {
340
337
if ($ package ->getState () === null ) {
338
+ $ pid = $ this ->getPid ($ package );
339
+
340
+ // When $pid comes back as null the child process for this package has not yet started; prevents both
341
+ // hanging until timeout expires (which was behaviour in 2.2.x) and the type error from strict_types
342
+ if ($ pid === null ) {
343
+ return false ;
344
+ }
345
+
341
346
// phpcs:ignore Magento2.Functions.DiscouragedFunction
342
- $ pid = pcntl_waitpid ($ this -> getPid ( $ package ) , $ status , WNOHANG );
343
- if ($ pid === $ this -> getPid ( $ package ) ) {
347
+ $ result = pcntl_waitpid ($ pid , $ status , WNOHANG );
348
+ if ($ result === $ pid ) {
344
349
$ package ->setState (Package::STATE_COMPLETED );
350
+ // phpcs:ignore Magento2.Functions.DiscouragedFunction
351
+ $ exitStatus = pcntl_wexitstatus ($ status );
352
+
353
+ $ this ->logger ->info (
354
+ "Exited: " . $ package ->getPath () . "(status: $ exitStatus) " ,
355
+ [
356
+ 'process ' => $ package ->getPath (),
357
+ 'status ' => $ exitStatus ,
358
+ ]
359
+ );
345
360
346
361
unset($ this ->inProgress [$ package ->getPath ()]);
347
362
// phpcs:ignore Magento2.Functions.DiscouragedFunction
348
363
return pcntl_wexitstatus ($ status ) === 0 ;
364
+ } elseif ($ result === -1 ) {
365
+ // phpcs:ignore Magento2.Functions.DiscouragedFunction
366
+ $ errno = pcntl_errno ();
367
+ // phpcs:ignore Magento2.Functions.DiscouragedFunction
368
+ $ strerror = pcntl_strerror ($ errno );
369
+
370
+ throw new \RuntimeException (
371
+ "Error encountered checking child process status (PID: $ pid): $ strerror (errno: $ errno) "
372
+ );
349
373
}
350
374
return false ;
351
375
}
@@ -361,7 +385,7 @@ private function isDeployed(Package $package)
361
385
*/
362
386
private function getPid (Package $ package )
363
387
{
364
- return isset ( $ this ->processIds [$ package ->getPath ()]) ?? null ;
388
+ return $ this ->processIds [$ package ->getPath ()] ?? null ;
365
389
}
366
390
367
391
/**
@@ -380,15 +404,30 @@ private function checkTimeout()
380
404
* Protect against zombie process
381
405
*
382
406
* @throws \RuntimeException
407
+ * @SuppressWarnings(PHPMD.UnusedLocalVariable)
383
408
* @return void
384
409
*/
385
410
public function __destruct ()
386
411
{
387
412
foreach ($ this ->inProgress as $ package ) {
413
+ $ pid = $ this ->getPid ($ package );
414
+ $ this ->logger ->info (
415
+ "Reaping child process: {$ package ->getPath ()} (PID: $ pid) " ,
416
+ [
417
+ 'process ' => $ package ->getPath (),
418
+ 'pid ' => $ pid ,
419
+ ]
420
+ );
421
+
388
422
// phpcs:ignore Magento2.Functions.DiscouragedFunction
389
- if (pcntl_waitpid ($ this ->getPid ($ package ), $ status ) === -1 ) {
423
+ if (pcntl_waitpid ($ pid , $ status ) === -1 ) {
424
+ // phpcs:ignore Magento2.Functions.DiscouragedFunction
425
+ $ errno = pcntl_errno ();
426
+ // phpcs:ignore Magento2.Functions.DiscouragedFunction
427
+ $ strerror = pcntl_strerror ($ errno );
428
+
390
429
throw new \RuntimeException (
391
- ' Error while waiting for package deployed: ' . $ this -> getPid ( $ package ) . ' ; Status: ' . $ status
430
+ " Error encountered waiting for child process (PID: $ pid ): $ strerror (errno: $ errno ) "
392
431
);
393
432
}
394
433
}
0 commit comments