Skip to content

Commit

Permalink
Implement proper error checking around pcntl_waitpid calls
Browse files Browse the repository at this point in the history
  • Loading branch information
davidalger committed May 2, 2019
1 parent 49b3c72 commit 7631cbc
Showing 1 changed file with 36 additions and 11 deletions.
47 changes: 36 additions & 11 deletions app/code/Magento/Deploy/Process/Queue.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@
use Magento\Deploy\Package\Package;
use Magento\Deploy\Service\DeployPackage;
use Magento\Framework\App\ResourceConnection;
use Psr\Log\LoggerInterface;
use Magento\Framework\App\State as AppState;
use Magento\Framework\Locale\ResolverInterface as LocaleResolver;
use Psr\Log\LoggerInterface;

/**
* Deployment Queue
Expand Down Expand Up @@ -165,6 +165,7 @@ public function process()
$packages = $this->packages;
while (count($packages) && $this->checkTimeout()) {
foreach ($packages as $name => $packageJob) {
// Unsets each member of $packages array (passed by reference) as each is executed
$this->assertAndExecute($name, $packages, $packageJob);
}
$this->logger->info('.');
Expand Down Expand Up @@ -224,12 +225,8 @@ private function assertAndExecute($name, array & $packages, array $packageJob)
* @param bool $dependenciesNotFinished
* @return void
*/
private function executePackage(
Package $package,
string $name,
array &$packages,
bool $dependenciesNotFinished
) {
private function executePackage(Package $package, string $name, array &$packages, bool $dependenciesNotFinished)
{
if (!$dependenciesNotFinished
&& !$this->isDeployed($package)
&& ($this->maxProcesses < 2 || (count($this->inProgress) < $this->maxProcesses))
Expand Down Expand Up @@ -339,13 +336,29 @@ private function isDeployed(Package $package)
if ($this->isCanBeParalleled()) {
if ($package->getState() === null) {
// phpcs:ignore Magento2.Functions.DiscouragedFunction
$pid = pcntl_waitpid($this->getPid($package), $status, WNOHANG);
if ($pid === $this->getPid($package)) {
$result = pcntl_waitpid($pid, $status, WNOHANG);
if ($result === $pid) {
$package->setState(Package::STATE_COMPLETED);
$exitStatus = pcntl_wexitstatus($status);

$this->logger->info(
"Exited: " . $package->getPath() . "(status: $exitStatus)",
[
'process' => $package->getPath(),
'status' => $exitStatus,
]
);

unset($this->inProgress[$package->getPath()]);
// phpcs:ignore Magento2.Functions.DiscouragedFunction
return pcntl_wexitstatus($status) === 0;
} elseif ($result === -1) {
$errno = pcntl_errno();
$strerror = pcntl_strerror($errno);

throw new \RuntimeException(
"Error encountered checking child process status (PID: $pid): $strerror (errno: $errno)"
);
}
return false;
}
Expand Down Expand Up @@ -385,10 +398,22 @@ private function checkTimeout()
public function __destruct()
{
foreach ($this->inProgress as $package) {
$pid = $this->getPid($package);
$this->logger->info(
"Reaping child process: {$package->getPath()} (PID: $pid)",
[
'process' => $package->getPath(),
'pid' => $pid,
]
);

// phpcs:ignore Magento2.Functions.DiscouragedFunction
if (pcntl_waitpid($this->getPid($package), $status) === -1) {
if (pcntl_waitpid($pid, $status) === -1) {
$errno = pcntl_errno();
$strerror = pcntl_strerror($errno);

throw new \RuntimeException(
'Error while waiting for package deployed: ' . $this->getPid($package) . '; Status: ' . $status
"Error encountered waiting for child process (PID: $pid): $strerror (errno: $errno)"
);
}
}
Expand Down

0 comments on commit 7631cbc

Please sign in to comment.