Magento 2 Documentation  2.3
Documentation for Magento 2 CMS v2.3 (December 2018)
ProcessManager.php
Go to the documentation of this file.
1 <?php
6 declare(strict_types=1);
7 
8 namespace Magento\Indexer\Model;
9 
14 {
18  const THREADS_COUNT = 'MAGE_INDEXER_THREADS_COUNT';
19 
21  private $failInChildProcess = false;
22 
24  private $resource;
25 
27  private $registry;
28 
30  private $threadsCount;
31 
37  public function __construct(
38  \Magento\Framework\App\ResourceConnection $resource,
39  \Magento\Framework\Registry $registry = null,
40  int $threadsCount = null
41  ) {
42  $this->resource = $resource;
43  if (null === $registry) {
45  \Magento\Framework\Registry::class
46  );
47  }
48  $this->registry = $registry;
49  $this->threadsCount = (int)$threadsCount;
50  }
51 
57  public function execute($userFunctions)
58  {
59  if ($this->threadsCount > 1 && $this->isCanBeParalleled() && !$this->isSetupMode() && PHP_SAPI == 'cli') {
60  $this->multiThreadsExecute($userFunctions);
61  } else {
62  $this->simpleThreadExecute($userFunctions);
63  }
64  }
65 
71  private function simpleThreadExecute($userFunctions)
72  {
73  foreach ($userFunctions as $userFunction) {
74  call_user_func($userFunction);
75  }
76  }
77 
84  private function multiThreadsExecute($userFunctions)
85  {
86  $this->resource->closeConnection(null);
87  $threadNumber = 0;
88  foreach ($userFunctions as $userFunction) {
89  $pid = pcntl_fork();
90  if ($pid == -1) {
91  throw new \RuntimeException('Unable to fork a new process');
92  } elseif ($pid) {
93  $this->executeParentProcess($threadNumber);
94  } else {
95  $this->startChildProcess($userFunction);
96  }
97  }
98  while (pcntl_waitpid(0, $status) != -1) {
99  //Waiting for the completion of child processes
100  }
101 
102  if ($this->failInChildProcess) {
103  throw new \RuntimeException('Fail in child process');
104  }
105  }
106 
112  private function isCanBeParalleled(): bool
113  {
114  return function_exists('pcntl_fork');
115  }
116 
122  private function isSetupMode(): bool
123  {
124  return $this->registry->registry('setup-mode-enabled') ?: false;
125  }
126 
133  private function startChildProcess(callable $userFunction)
134  {
135  $status = call_user_func($userFunction);
136  $status = is_integer($status) ? $status : 0;
137  exit($status);
138  }
139 
145  private function executeParentProcess(int &$threadNumber)
146  {
147  $threadNumber++;
148  if ($threadNumber >= $this->threadsCount) {
149  pcntl_wait($status);
150  if (pcntl_wexitstatus($status) !== 0) {
151  $this->failInChildProcess = true;
152  }
153  $threadNumber--;
154  }
155  }
156 }
elseif(isset( $params[ 'redirect_parent']))
Definition: iframe.phtml:17
__construct(\Magento\Framework\App\ResourceConnection $resource, \Magento\Framework\Registry $registry=null, int $threadsCount=null)
$resource
Definition: bulk.php:12
exit
Definition: redirect.phtml:12
$status
Definition: order_status.php:8