/** * @param callable $operation * * @throws Exception\LogicException * * @return mixed|$this */ private function transactKillSwitch(callable $operation) { $ksPath = $this->bootstrapProfile->getKillSwitchPath(); if ($ksPath === null) { throw new Exception\LogicException('No kill switch has been configured'); } $lock = Lock::acquire(); $kswitch = new KillSwitch($ksPath); $retval = call_user_func($operation, $kswitch); $kswitch->save(); $lock->release(); return $retval !== null ? $retval : $this; }
/** * @param OutputInterface $output * @param WorkerBootstrapProfile $profile * @param string $name * @param bool $local * @param string $wFactory */ private function stopWorkerWithMessage(OutputInterface $output, WorkerBootstrapProfile $profile, $name, $local, $wFactory) { if ($profile->getAdminCookie() !== null) { if ($this->getRegistry()->stopSharedWorker($name)) { $output->writeln('Sent stop message to ' . ($local ? 'local' : 'remote') . ' worker <comment>' . $name . '</comment>.'); } else { $output->writeln(($local ? 'Local' : 'Remote') . ' worker <comment>' . $name . '</comment> was not running.'); } } else { $output->writeln('Couldn\'t send stop message to ' . ($local ? 'local' : 'remote') . ' worker <comment>' . $name . '</comment> (please configure an admin cookie on factory <comment>' . $wFactory . '</comment> for this feature to work).'); } }
/** * @param string $socketAddress * @param WorkerBootstrapProfile $bootstrapProfile * * @throws Exception\LogicException * @throws Exception\RuntimeException * * @return Status\WorkerStatus */ public static function queryWorker($socketAddress, WorkerBootstrapProfile $bootstrapProfile) { $adminCookie = $bootstrapProfile->getAdminCookie(); $channel = self::connect($socketAddress, $bootstrapProfile); AdminEncoding::sendQueryMessage($channel, $adminCookie); for (;;) { $message = $channel->receiveMessage(); $status = AdminEncoding::getStatusMessage($message); if ($status !== null) { return $status; } } }
/** * @param WorkerBootstrapProfile $bootstrapProfile * @param string $implementationClassName * @param int|null $workerCount * * @throws Exception\InvalidArgumentException * @throws Exception\RuntimeException * * @return static */ public static function withClass(WorkerBootstrapProfile $bootstrapProfile, $implementationClassName, $workerCount = null) { return new static($bootstrapProfile, $bootstrapProfile->generateExpression($implementationClassName), $workerCount); }
/** * @param string $service * * @return string */ public static function generateServiceExpression($service) { return '$kernel->getContainer()->get(' . WorkerBootstrapProfile::exportPhpValue($service) . ')'; }
/** * @param ContainerBuilder $container * @param string $name * * @return Definition */ private function createBootstrapProfileDefinition(ContainerBuilder $container, $name) { $killSwitchPath = dirname($container->getParameter('kernel.root_dir')) . DIRECTORY_SEPARATOR . 'var' . DIRECTORY_SEPARATOR . 'exsyst_worker' . DIRECTORY_SEPARATOR . 'kill_switch.' . $name . '.json'; $definition = new Definition(WorkerBootstrapProfile::class, [false]); $definition->addMethodCall('addScriptToRequire', [dirname(dirname($container->getParameter('kernel.cache_dir'))) . '/bootstrap.php.cache']); $definition->addMethodCall('addScriptToRequire', [$container->getParameter('kernel.root_dir') . '/AppKernel.php']); $definition->addMethodCall('addStage2GlobalVariableWithExpression', ['kernel', 'new AppKernel(' . WorkerBootstrapProfile::exportPhpValue($container->getParameter('kernel.environment')) . ', ' . WorkerBootstrapProfile::exportPhpValue($container->getParameter('kernel.debug')) . ')']); $definition->addMethodCall('addStage2Part', ['$kernel->loadClassCache();']); $definition->addMethodCall('addStage2Part', ['$kernel->boot();']); $definition->addMethodCall('addStage3Part', ['if ($workerImpl instanceof ' . ContainerAwareInterface::class . ') {' . PHP_EOL . ' $workerImpl->setContainer($kernel->getContainer());' . PHP_EOL . '}']); $definition->addMethodCall('setAdminCookie', [rtrim(strtr(base64_encode(hash_hmac('sha512', $killSwitchPath, $container->getParameter('kernel.secret'), true)), '+/', '-_'), '=')]); $definition->addMethodCall('setKillSwitchPath', [$killSwitchPath]); $definition->setPublic(false); return $definition; }