/** * @override * @inheritDoc */ public function createProcess($alias, $name, $flags = Runtime::CREATE_DEFAULT, $params = []) { if (isset($this->processes[$alias])) { if ($name === null || $name === 'null') { $name = $this->processes[$alias]['name']; } $manager = $this; if ($flags === Runtime::CREATE_DEFAULT && $this->processes[$alias]['verified'] === false) { $req = $this->createRequest($this->channel, $alias, new RuntimeCommand('cmd:ping', $params)); return $req->call()->then(function () { return 'Process has been created.'; }, function () use($manager, $alias, $name, $params) { return $manager->createProcess($alias, $name, Runtime::CREATE_FORCE_HARD, $params); }); } else { if ($flags === Runtime::CREATE_FORCE_SOFT) { return $this->destroyProcess($alias, Runtime::DESTROY_FORCE_SOFT, $params)->then(function () use($manager, $alias, $name, $params) { return $manager->createProcess($alias, $name, $params); }); } else { if ($flags === Runtime::CREATE_FORCE_HARD) { return $this->destroyProcess($alias, Runtime::DESTROY_FORCE_HARD, $params)->then(function () use($manager, $alias, $name, $params) { return $manager->createProcess($alias, $name, $params); }); } else { if ($flags === Runtime::CREATE_FORCE) { return $this->destroyProcess($alias, Runtime::DESTROY_FORCE, $params)->then(function () use($manager, $alias, $name, $params) { return $manager->createProcess($alias, $name, $params); }); } else { return Promise::doReject(new ResourceOccupiedException('Process with such alias already exists.')); } } } } } else { if ($name === null) { return Promise::doReject(new InvalidArgumentException('Name of new process cannot be null.')); } } $pid = $this->system->run($this->phpCommand('kraken.process', [$this->runtime->getAlias(), $alias, $name], $this->context)); if (!$this->system->existsPid($pid)) { return Promise::doReject(new ResourceOccupiedException('Process could not be created.')); } if (!$this->allocateProcess($alias, $name, $pid)) { return Promise::doReject(new ResourceOccupiedException('Process could not be created because of storage failure.')); } $req = $this->createRequest($this->channel, $alias, new RuntimeCommand('cmd:ping', $params)); return $req->call()->then(function () { return 'Process has been created.'; }, function ($reason) use($alias) { $this->freeProcess($alias); throw $reason; }, function ($reason) use($alias) { $this->freeProcess($alias); return $reason; }); }
/** * @param RuntimeContainerInterface $runtime * @param ChannelInterface $channel * @param SystemInterface $system * @param FilesystemInterface $fs * @throws InstantiationException */ public function __construct(RuntimeContainerInterface $runtime, ChannelInterface $channel, SystemInterface $system, FilesystemInterface $fs) { $this->runtime = $runtime; $this->channel = $channel; $this->system = $system; $this->fs = $fs; $core = $runtime->getCore(); $this->scriptRoot = $core->getDataPath() . '/autorun'; $this->fsPath = $core->getDataDir() . '/storage/project/project.json'; $this->projectRoot = 'Main'; $this->projectName = 'Main'; $this->data = $this->getEmptyStorage(); try { $this->data = $this->selectFromStorage(); } catch (Error $ex) { throw new InstantiationException('ProjectManager could not be initialized.', $ex); } catch (Exception $ex) { throw new InstantiationException('ProjectManager could not be initialized.', $ex); } }
/** * @param RuntimeContainerInterface $runtime * @param ChannelCompositeInterface $composite * @param ConfigInterface $config */ private function registerRuntimeSupervision(RuntimeContainerInterface $runtime, ChannelCompositeInterface $composite, ConfigInterface $config) { $timerCollection = new TimerCollection(); $channel = $composite->getBus('slave'); $keepalive = $config->get('project.tolerance.child.keepalive'); $channel->on('disconnect', function ($alias) use($runtime, $keepalive, $timerCollection) { if ($keepalive <= 0) { return; } $timer = $runtime->getLoop()->addTimer($keepalive, function () use($alias, $runtime, $timerCollection) { $timerCollection->removeTimer($alias); $runtime->fail(new ChildUnresponsiveException("Child runtime [{$alias}] is unresponsive."), ['origin' => $alias]); }); $timerCollection->addTimer($alias, $timer); }); $channel->on('connect', function ($alias) use($timerCollection) { if (($timer = $timerCollection->getTimer($alias)) !== null) { $timer->cancel(); $timerCollection->removeTimer($alias); } }); $channel = $composite->getBus('master'); $keepalive = $config->get('project.tolerance.parent.keepalive'); $channel->on('disconnect', function ($alias) use($runtime, $keepalive, $timerCollection) { if ($keepalive <= 0) { return; } $timer = $runtime->getLoop()->addTimer($keepalive, function () use($alias, $runtime, $timerCollection) { $timerCollection->removeTimer($alias); $runtime->fail(new ParentUnresponsiveException("Parent runtime [{$alias}] is unresponsive."), ['origin' => $alias]); }); $timerCollection->addTimer($alias, $timer); }); $channel->on('connect', function ($alias) use($timerCollection) { if (($timer = $timerCollection->getTimer($alias)) !== null) { $timer->cancel(); $timerCollection->removeTimer($alias); } }); }
/** * @override * @inheritDoc */ public function createThread($alias, $name, $flags = Runtime::CREATE_DEFAULT, $params = []) { if (isset($this->threads[$alias])) { if ($name === null) { $name = $this->threads[$alias]->name; } $manager = $this; if ($flags === Runtime::CREATE_FORCE_SOFT) { return $this->destroyThread($alias, Runtime::DESTROY_FORCE_SOFT, $params)->then(function () use($manager, $alias, $name, $params) { return $manager->createThread($alias, $name, $params); }); } else { if ($flags === Runtime::CREATE_FORCE_HARD) { return $this->destroyThread($alias, Runtime::DESTROY_FORCE_HARD, $params)->then(function () use($manager, $alias, $name, $params) { return $manager->createThread($alias, $name, $params); }); } else { if ($flags === Runtime::CREATE_FORCE) { return $this->destroyThread($alias, Runtime::DESTROY_FORCE, $params)->then(function () use($manager, $alias, $name, $params) { return $manager->createThread($alias, $name, $params); }); } else { return Promise::doReject(new ResourceOccupiedException('Thread with such alias already exists.')); } } } } else { if ($name === null) { return Promise::doReject(new InvalidArgumentException('Name of new thread cannot be null.')); } } global $loader; $controller = new ThreadController($loader); $wrapper = new ThreadWrapper($controller, $this->runtime->getCore()->getDataPath(), $this->runtime->getAlias(), $alias, $name, $this->context); $wrapper->start(PTHREADS_INHERIT_ALL); $this->allocateThread($alias, $wrapper); $req = $this->createRequest($this->channel, $alias, new RuntimeCommand('cmd:ping', $params)); return $req->call()->then(function () { return 'Thread has been created.'; }, function ($reason) use($alias) { $this->freeThread($alias); return $reason; }, function ($reason) use($alias) { $this->freeThread($alias); return $reason; }); }
/** * @param RuntimeContainerInterface $runtime * @param ChannelCompositeInterface $composite * @param ProtocolInterface $protocol */ private function executeProtocol(RuntimeContainerInterface $runtime, ChannelCompositeInterface $composite, ProtocolInterface $protocol) { /** * If the json_decode fails, it means the received message is leftover of request response, * hence it should be dropped. */ try { $params = json_decode($protocol->getMessage(), true); $command = array_shift($params); $params['origin'] = $protocol->getOrigin(); if (!$runtime->isFailed() || isset($params['hash']) && $runtime->getHash() === $params['hash']) { $promise = $this->executeCommand($command, $params); } else { $promise = Promise::doReject(new RejectionException('Container is currently in failed state and cannot execute any tasks.')); } if ($protocol->getType() === Channel::TYPE_REQ) { $promise->then(function ($response) use($composite, $protocol, $command) { return (new Response($composite, $protocol, $response))->call(); }, function ($reason) use($composite, $protocol) { return (new Response($composite, $protocol, $reason))->call(); }, function ($reason) use($composite, $protocol) { return (new Response($composite, $protocol, $reason))->call(); }); } } catch (Error $ex) { return; } catch (Exception $ex) { return; } }
/** * @param RuntimeContainerInterface $runtime * @param ChannelInterface $channel */ public function __construct(RuntimeContainerInterface $runtime, ChannelInterface $channel, $receiver = null) { $this->runtime = $runtime; $this->channel = $channel; $this->receiver = $receiver !== null ? $receiver : $runtime->getParent(); }