protected function doStart(Console $console) : \Generator { if (yield from $this->checkCommands($console)) { return; } $this->recommendAssertionSetting(); $this->recommendLogLevel($console); $this->stopPromisor = null; $this->console = $console; $this->workerCount = $this->determineWorkerCount($console); $this->ipcServerUri = $this->bindIpcServer(); $this->workerCommand = $this->generateWorkerCommand($console); yield from $this->bindCommandServer((string) $console->getArg("config")); $promises = []; for ($i = 0; $i < $this->workerCount; $i++) { $promises[] = $this->spawn(); } (yield \Amp\any($promises)); }
/** * @param Manager $args * @return \Generator */ private function doExecute(Manager $args) { $configPath = $args->get("config"); try { $config = Yaml::parse((yield \Amp\File\get($configPath))); } catch (FilesystemException $e) { $this->climate->error("Config file ({$configPath}) not found."); (yield new CoroutineResult(self::EXIT_CONFIG_ERROR)); return; } catch (ParseException $e) { $this->climate->error("Config file ({$configPath}) had an invalid format and couldn't be parsed."); (yield new CoroutineResult(self::EXIT_CONFIG_ERROR)); return; } if ($args->defined("server")) { $config["server"] = $args->get("server"); } else { if (!isset($config["server"]) && $args->exists("server")) { $config["server"] = $args->get("server"); } } if ($args->defined("storage")) { $config["storage"] = $args->get("storage"); } else { if (!isset($config["storage"]) && $args->exists("storage")) { $config["storage"] = $args->get("storage"); } } if (!isset($config["server"])) { $this->climate->error("Config file ({$configPath}) didn't have a 'server' set nor was it passed as command line argument."); (yield new CoroutineResult(self::EXIT_CONFIG_ERROR)); return; } if (!isset($config["storage"])) { $this->climate->error("Config file ({$configPath}) didn't have a 'storage' set nor was it passed as command line argument."); (yield new CoroutineResult(self::EXIT_CONFIG_ERROR)); return; } if (!isset($config["email"])) { $this->climate->error("Config file ({$configPath}) didn't have a 'email' set."); (yield new CoroutineResult(self::EXIT_CONFIG_ERROR)); return; } if (!isset($config["certificates"]) || !is_array($config["certificates"])) { $this->climate->error("Config file ({$configPath}) didn't have a 'certificates' section that's an array."); (yield new CoroutineResult(self::EXIT_CONFIG_ERROR)); return; } $command = implode(" ", array_map("escapeshellarg", [PHP_BINARY, $GLOBALS["argv"][0], "setup", "--server", $config["server"], "--storage", $config["storage"], "--email", $config["email"]])); $process = new Process($command); $result = (yield $process->exec(Process::BUFFER_ALL)); if ($result->exit !== 0) { $this->climate->error("Registration failed ({$result->exit})"); $this->climate->error($command); $this->climate->br()->out($result->stdout); $this->climate->br()->error($result->stderr); (yield new CoroutineResult(self::EXIT_SETUP_ERROR)); return; } $certificateChunks = array_chunk($config["certificates"], 10, true); $errors = []; $values = []; foreach ($certificateChunks as $certificateChunk) { $promises = []; foreach ($certificateChunk as $certificate) { $promises[] = \Amp\resolve($this->checkAndIssue($certificate, $config["server"], $config["storage"])); } list($chunkErrors, $chunkValues) = (yield \Amp\any($promises)); $errors += $chunkErrors; $values += $chunkValues; } $status = ["no_change" => count(array_filter($values, function ($value) { return $value === self::STATUS_NO_CHANGE; })), "renewed" => count(array_filter($values, function ($value) { return $value === self::STATUS_RENEWED; })), "failure" => count($errors)]; if ($status["renewed"] > 0) { foreach ($values as $i => $value) { if ($value === self::STATUS_RENEWED) { $certificate = $config["certificates"][$i]; $this->climate->info("Certificate for " . implode(", ", array_keys($this->toDomainPathMap($certificate["paths"]))) . " successfully renewed."); } } } if ($status["failure"] > 0) { foreach ($errors as $i => $error) { $certificate = $config["certificates"][$i]; $this->climate->error("Issuance for the following domains failed: " . implode(", ", array_keys($this->toDomainPathMap($certificate["paths"])))); $this->climate->error("Reason: {$error}"); } $exitCode = $status["renewed"] > 0 ? self::EXIT_ISSUANCE_PARTIAL : self::EXIT_ISSUANCE_ERROR; (yield new CoroutineResult($exitCode)); return; } if ($status["renewed"] > 0) { (yield new CoroutineResult(self::EXIT_ISSUANCE_OK)); return; } }
protected function execute(InputInterface $input, OutputInterface $output) { set_time_limit(10800); // 3 hours is the maximum for this command. Need more? You really screwed something, full suite for all Oblivion vanilla data takes 20 minutes. :) try { $target = $input->getArgument('target'); $this->threadsNumber = $input->getArgument('threadsNumber'); $buildTarget = BuildTargetFactory::get($target); if (count(array_slice(scandir($buildTarget->getWorkspacePath()), 2)) > 0 || count(array_slice(scandir($buildTarget->getTranspiledPath()), 2)) > 0 || count(array_slice(scandir($buildTarget->getArtifactsPath()), 2)) > 0) { $output->writeln("Target " . $target . " current build dir not clean, archive it manually."); return; } $output->writeln("Starting transpiling reactor using " . $this->threadsNumber . " threads..."); $reactor = \Amp\reactor(); $reactor->run(function () use($buildTarget, $output, $reactor) { $errorLog = fopen($buildTarget->getErrorLogPath(), "w+"); $sourceFiles = array_slice(scandir($buildTarget->getSourcePath()), 2); $buildPlanBuilder = new TES5BuildPlanBuilder(unserialize(file_get_contents('app/graph'))); $buildPlan = $buildPlanBuilder->createBuildPlan($sourceFiles, $this->threadsNumber); $totalSourceFiles = count($sourceFiles); $progressBar = new CliProgressBar($totalSourceFiles); $progressBar->display(); $promises = []; foreach ($buildPlan as $threadBuildPlan) { $task = new TranspileChunkJob($buildTarget->getTargetName(), $threadBuildPlan); $deferred = new \Amp\Deferred(); \Amp\once(function () use($deferred, $task) { $task->runTask($deferred); }, 0); $promise = $deferred->promise(); $promise->when(function (\Exception $e = null, $return = null) use($output, $errorLog) { if ($e) { $output->writeln('Exception ' . get_class($e) . ' occurred in one of the threads while transpiling, progress bar will not be accurate..'); fwrite($errorLog, get_class($e) . PHP_EOL . $e->getMessage() . PHP_EOL); } }); $promise->watch(function ($data) use($progressBar, $errorLog) { $progressBar->progress(count($data['scripts'])); if (isset($data['exception'])) { fwrite($errorLog, implode(', ', $data['scripts']) . PHP_EOL . $data['exception']); } }); $promises[] = $promise; } /** * @var Promise $transpilingPromise */ $transpilingPromise = \Amp\any($promises); $transpilingPromise->when(function () use($reactor, $progressBar, $errorLog) { $progressBar->end(); fclose($errorLog); $reactor->stop(); }); }); $output->writeln("Preparing build workspace..."); /* * * @TODO - Create a factory that will provide a PrepareWorkspaceJob based on running system, so we can provide a * native implementation for Windows */ $prepareCommand = new PrepareWorkspaceJob($buildTarget->getTargetName()); $prepareCommand->run(); $output->writeln("Workspace prepared..."); $task = new CompileScriptJob($buildTarget->getTargetName()); $task->run(); $output->writeln("Build completed, archiving ..."); /* * * @TODO - Create a factory that will provide a PrepareWorkspaceJob based on running system, so we can provide a * native implementation for Windows */ $prepareCommand = new ArchiveBuildJob($buildTarget->getTargetName()); $prepareCommand->run(); } catch (\LogicException $e) { $output->writeln("Unknown target " . $target . ", exiting."); return; } catch (\Exception $e) { var_dump($e->getMessage()); exit; } }
/** * @param $domains * @throws AcmeException */ private function checkDnsRecords($domains) { $promises = []; foreach ($domains as $domain) { $promises[$domain] = \Amp\Dns\resolve($domain, ["types" => [Record::A], "hosts" => false]); } list($errors) = (yield \Amp\any($promises)); if (!empty($errors)) { throw new AcmeException("Couldn't resolve the following domains to an IPv4 record: " . implode(", ", array_keys($errors))); } }
private function checkDnsRecords($domains) { $errors = []; $domainChunks = array_chunk($domains, 10, true); foreach ($domainChunks as $domainChunk) { $promises = []; foreach ($domainChunk as $domain) { $promises[$domain] = \Amp\Dns\resolve($domain, ["types" => [Record::A, Record::AAAA], "hosts" => false]); } list($chunkErrors) = (yield \Amp\any($promises)); $errors += $chunkErrors; } if (!empty($errors)) { throw new AcmeException("Couldn't resolve the following domains to an IPv4 nor IPv6 record: " . implode(", ", array_keys($errors))); } }