protected function spawnProcess() { $processOptions = isset($this->options['processOptions']) ? $this->options['processOptions'] : []; $process = clone $this->sourceProcess; Factory::parent($process, $this->loop, $processOptions)->then(function (Messenger $messenger) { Util::forwardEvents($messenger, $this, ['error']); $this->pool->attach($messenger); $this->readyPool->enqueue($messenger); $this->emit('messenger', [$messenger, $this]); }, function ($error) { $this->emit('error', [$error, $this]); }); }
/** * Sets the event loop instance. * * @param \React\EventLoop\LoopInterface $loop * * @todo find some way to do a unit test for this method */ public function setLoop(LoopInterface $loop) { parent::setLoop($loop); \React\Promise\Timer\timeout(MessengerFactory::parentFromClass('PSchwisow\\Phergie\\Plugin\\Karma\\ChildProcess', $loop), 10.0, $loop)->then(function (Messenger $messenger) use($loop) { $this->logDebug('got a messenger'); $this->messenger = $messenger; $messenger->on('error', function ($e) { $this->logDebug('Error: ' . var_export($e, true)); }); $this->messenger->rpc(MessageFactory::rpc('config', $this->config))->then(function ($payload) { $this->logDebug('configuration sent to child. Response: ' . var_export($payload, true)); }); }, function ($error) { if ($error instanceof \React\Promise\Timer\TimeoutException) { // the operation has failed due to a timeout $this->logDebug('TIMEOUT'); } else { // the input operation has failed due to some other error $this->logDebug('OTHER ERROR'); } }); }
protected function spawnProcessAtAddress($address) { $this->startingProcesses++; unset($this->availableAddresses[$address]); $processOptions = isset($this->options['processOptions']) ? $this->options['processOptions'] : []; $process = $this->rebuildProcess($address); Factory::parent($process, $this->loop, $processOptions)->then(function (Messenger $messenger) use($address) { $this->startingProcesses--; $this->pool->attach($messenger); $this->readyPool->enqueue($messenger); $this->emit('messenger', [$messenger, $this]); $this->coreMessengerMapping[spl_object_hash($messenger)] = $address; $messenger->on('exit', function () use($messenger, $address) { $this->pool->detach($messenger); $this->availableAddresses[$address] = $address; unset($this->coreMessengerMapping[spl_object_hash($messenger)]); $messengers = []; while ($this->readyPool->count() > 0) { $queuedMessenger = $this->readyPool->dequeue(); if ($queuedMessenger === $messenger) { continue; } $messengers[] = $queuedMessenger; } array_walk($messengers, function (Messenger $messenger) { $this->readyPool->enqueue($messenger); }); if ($this->callQueue->count() > 0 && $this->readyPool->count() <= $this->options['min_size'] && $this->startingProcesses + $this->pool->count() < $this->options['max_size']) { $this->spawnProcess(); } }); }, function ($error) { $this->startingProcesses--; $this->emit('error', [$error, $this]); }); }
/** * @param LoopInterface $loop * @param array $options * @return PromiseInterface * @throws \Exception */ public function __invoke(LoopInterface $loop, array $options) { return Factory::parent(clone $this->process, $loop, $options); }
<?php use React\EventLoop\Factory as LoopFactory; use WyriHaximus\React\ChildProcess\Messenger\ArgvEncoder; use WyriHaximus\React\ChildProcess\Messenger\Factory as MessengerFactory; use WyriHaximus\React\ChildProcess\Messenger\Process; foreach ([__DIR__ . '/../vendor/autoload.php', __DIR__ . '/../../../autoload.php'] as $file) { if (file_exists($file)) { require $file; break; } } $arguments = ''; if (isset($argv[1])) { $arguments = $argv[1]; } $loop = LoopFactory::create(); $messenger = MessengerFactory::child($loop, ArgvEncoder::decode($arguments)); Process::create($loop, $messenger); $loop->run();
/** * @param LoopInterface $loop * @param array $options * @return PromiseInterface * @throws \Exception */ public function __invoke(LoopInterface $loop, array $options) { $options = array_merge($options, $this->overrideOptions); return Factory::parentFromClass($this->className, $loop, $options); }