11 use Psr\Log\LoggerInterface;
35 private $packages = [];
40 private $processIds = [];
45 private $inProgress = [];
50 private $maxProcesses;
65 private $localeResolver;
70 private $resourceConnection;
80 private $deployPackageService;
85 private $options = [];
95 private $lastJobStarted = 0;
109 LocaleResolver $localeResolver,
114 $maxProcesses = self::DEFAULT_MAX_PROCESSES_AMOUNT,
115 $maxExecTime = self::DEFAULT_MAX_EXEC_TIME
117 $this->appState = $appState;
118 $this->localeResolver = $localeResolver;
121 $this->deployPackageService = $deployPackageService;
122 $this->options = $options;
123 $this->maxProcesses = $maxProcesses;
124 $this->maxExecTime = $maxExecTime;
132 public function add(
Package $package, array $dependencies = [])
134 $this->packages[$package->
getPath()] = [
135 'package' => $package,
136 'dependencies' => $dependencies
147 return $this->packages;
158 $this->start = $this->lastJobStarted =
time();
159 $packages = $this->packages;
160 while (count($packages) && $this->checkTimeout()) {
161 foreach ($packages as
$name => $packageJob) {
162 $this->assertAndExecute(
$name, $packages, $packageJob);
164 $this->logger->info(
'.');
166 foreach ($this->inProgress as
$name => $package) {
167 if ($this->isDeployed($package)) {
168 unset($this->inProgress[
$name]);
173 $this->awaitForAllProcesses();
175 return $returnStatus;
186 private function assertAndExecute(
$name, array & $packages, array $packageJob)
189 $package = $packageJob[
'package'];
190 $dependenciesNotFinished =
false;
191 if ($package->getParent() && $package->getParent() !== $package) {
192 foreach ($packageJob[
'dependencies'] as $dependencyName => $dependency) {
193 if (!$this->isDeployed($dependency)) {
196 if (!array_key_exists($dependencyName, $packages)) {
197 $dependenciesNotFinished =
true;
199 $this->assertAndExecute(
202 $packages[$dependencyName]
208 $this->executePackage($package,
$name, $packages, $dependenciesNotFinished);
218 private function executePackage(
222 bool $dependenciesNotFinished
224 if (!$dependenciesNotFinished
225 && !$this->isDeployed($package)
226 && ($this->maxProcesses < 2 || (count($this->inProgress) < $this->maxProcesses))
228 unset($packages[
$name]);
229 $this->execute($package);
238 private function awaitForAllProcesses()
240 while ($this->inProgress && $this->checkTimeout()) {
241 foreach ($this->inProgress as
$name => $package) {
242 if ($this->isDeployed($package)) {
243 unset($this->inProgress[
$name]);
246 $this->logger->info(
'.');
249 if ($this->isCanBeParalleled()) {
251 $this->resourceConnection->closeConnection();
258 private function isCanBeParalleled()
268 private function execute(Package $package)
270 $this->lastJobStarted =
time();
272 "Execute: " . $package->getPath(),
274 'process' => $package->getPath(),
275 'count' => count($package->getFiles()),
279 $this->appState->emulateAreaCode(
281 function () use ($package) {
283 $this->localeResolver->setLocale($package->getLocale());
287 foreach ($package->getPreProcessors() as
$processor) {
288 $processor->process($package, $this->options);
293 if ($this->isCanBeParalleled()) {
296 throw new \RuntimeException(
'Unable to fork a new process');
300 $this->inProgress[$package->getPath()] = $package;
301 $this->processIds[$package->getPath()] = $pid;
306 $this->inProgress = [];
307 $this->deployPackageService->deploy($package, $this->options,
true);
310 $this->deployPackageService->deploy($package, $this->options);
319 private function isDeployed(Package $package)
321 if ($this->isCanBeParalleled()) {
322 if ($package->getState() ===
null) {
323 $pid = pcntl_waitpid($this->getPid($package),
$status, WNOHANG);
324 if ($pid === $this->getPid($package)) {
327 unset($this->inProgress[$package->getPath()]);
328 return pcntl_wexitstatus(
$status) === 0;
333 return $package->getState();
340 private function getPid(Package $package)
342 return isset($this->processIds[$package->getPath()])
343 ? $this->processIds[$package->getPath()]
350 private function checkTimeout()
352 return time() - $this->lastJobStarted < $this->maxExecTime;
364 foreach ($this->inProgress as $package) {
365 if (pcntl_waitpid($this->getPid($package),
$status) === -1) {
366 throw new \RuntimeException(
367 'Error while waiting for package deployed: ' . $this->getPid($package) .
'; Status: ' .
$status
const DEFAULT_MAX_EXEC_TIME
const DEFAULT_MAX_PROCESSES_AMOUNT
__construct(AppState $appState, LocaleResolver $localeResolver, ResourceConnection $resourceConnection, LoggerInterface $logger, DeployPackage $deployPackageService, array $options=[], $maxProcesses=self::DEFAULT_MAX_PROCESSES_AMOUNT, $maxExecTime=self::DEFAULT_MAX_EXEC_TIME)
add(Package $package, array $dependencies=[])
if(!isset($_GET['name'])) $name