/** * @param WorkerBootstrapProfile $bootstrapProfile * @param string $implementationExpression */ protected function __construct(WorkerBootstrapProfile $bootstrapProfile, $implementationExpression) { $bootstrapProfile->getOrFindPhpExecutablePathAndArguments($php, $phpArgs); $bootstrapProfile->compileScriptWithExpression($implementationExpression, null, $scriptPath, $deleteScript); try { $line = array_merge([$php], $phpArgs, [$scriptPath]); $outPath = $bootstrapProfile->getOutputPath(); $this->process = proc_open(implode(' ', array_map('escapeshellarg', $line)), [0 => ['pipe', 'r'], 1 => ['pipe', 'w'], 2 => $outPath !== null ? ['file', $outPath, 'a'] : STDERR], $pipes); $inputSink = Sink::fromStream($pipes[0], true); $outputSource = Source::fromStream($pipes[1], true); $this->channel = $bootstrapProfile->getChannelFactory()->createChannel($outputSource, $inputSink); } catch (\Exception $e) { if (isset($pipes[1])) { fclose($pipes[1]); } if (isset($pipes[0])) { fclose($pipes[0]); } if (isset($this->process)) { proc_terminate($this->process); proc_close($this->process); } if ($deleteScript) { unlink($scriptPath); } throw $e; } }
/** * @param string $socketAddress * @param WorkerBootstrapProfile $bootstrapProfile * @param string $implementationExpression * @param Exception\ConnectException|null $e * * @throws Exception\ConnectException * @throws Exception\LogicException */ public static function startWithExpression($socketAddress, WorkerBootstrapProfile $bootstrapProfile, $implementationExpression, Exception\ConnectException $e = null) { if (!IdentificationHelper::isLocalAddress($socketAddress)) { if ($e) { throw $e; } else { throw new Exception\LogicException("Can't start the worker, because its socket address is not local"); } } $bootstrapProfile->getOrFindPhpExecutablePathAndArguments($php, $phpArgs); $bootstrapProfile->compileScriptWithExpression($implementationExpression, $socketAddress, $scriptPath, $deleteScript); try { $line = array_merge([$php], $phpArgs, [$scriptPath]); self::startDaemon($line, $bootstrapProfile->getOutputPath()); } catch (\Exception $e) { if ($deleteScript) { unlink($scriptPath); } throw $e; } }