SWOOLE_HOOK_ALL ^ SWOOLE_HOOK_BLOCKING_FUNCTION, 'enable_deadlock_check' => FALSE, 'exit_condition' => function () { return Coroutine::stats()['coroutine_num'] === 0; } ]); } /** * @param $process */ public function addProcess($process) { $this->process[] = $process; } /** * @return void * @throws ConfigException * @throws ContainerExceptionInterface * @throws NotFoundExceptionInterface * @throws Exception */ public function start(): void { $this->container->mapping(Emitter::class, ResponseEmitter::class); $this->container->mapping(ResponseInterface::class, Response::class); $this->container->mapping(RequestInterface::class, Request::class); $this->manager->initCoreServers(Config::get('server', [], true), $this->daemon); $rpcService = Config::get('rpc', []); if (!empty($rpcService)) { /** @var \Kiri\Server\Config $create */ $create = $this->container->create(\Kiri\Server\Config::class, [], $rpcService); $this->manager->addListener($create); } pcntl_signal(SIGINT, [$this, 'onSigint']); $this->onHotReload(); $this->processManager->batch($this->process, $this->manager->getServer()); $this->dispatch->dispatch(new OnServerBeforeStart()); $this->manager->start(); } /** * @return void * @throws Exception */ protected function onWorkerListener(): void { $this->provider->on(OnWorkerStop::class, '\Swoole\Timer::clearAll'); $this->provider->on(OnWorkerStart::class, [$this, 'setWorkerName']); $this->provider->on(OnTaskerStart::class, [$this, 'setTaskerName']); } /** * @param OnWorkerStart $onWorkerStart * @throws ConfigException */ public function setWorkerName(OnWorkerStart $onWorkerStart): void { $prefix = sprintf('Worker Process[%d].%d', $onWorkerStart->server->worker_pid, $onWorkerStart->workerId); set_env('environmental', Kiri::WORKER); Kiri::setProcessName($prefix); } /** * @param OnWorkerStart $onWorkerStart * @throws ConfigException */ public function setTaskerName(OnWorkerStart $onWorkerStart): void { $prefix = sprintf('Worker Process[%d].%d', $onWorkerStart->server->worker_pid, $onWorkerStart->workerId); set_env('environmental', Kiri::WORKER); Kiri::setProcessName($prefix); } /** * @return void * @throws ConfigException * @throws ReflectionException * @throws Exception */ public function onHotReload(): void { $this->onWorkerListener(); $reload = Config::get('reload.hot', false); if ($reload !== false) { $this->provider->on(OnWorkerStart::class, [$this, 'LoadRoutingList']); $this->process[] = Scaner::class; } else { $this->LoadRoutingList(); } } /** * @return void */ public function onSigint(): void { try { $this->dispatch->dispatch(new OnBeforeShutdown()); } catch (\Throwable $exception) { $this->logger->error($exception->getMessage()); } finally { $this->manager->getServer()->shutdown(); } } /** * @return void * @throws ReflectionException * @throws Exception */ public function LoadRoutingList(): void { scan_directory(MODEL_PATH, 'app\Model'); $this->router->scan_build_route(); } /** * @return void * @throws ConfigException * @throws ContainerExceptionInterface * @throws NotFoundExceptionInterface * @throws Exception */ public function shutdown(): void { $configs = Config::get('server', [], true); foreach ($this->manager->sortService($configs['ports'] ?? []) as $config) { $this->state->exit($config['port']); } $this->dispatch->dispatch(new OnShutdown()); } /** * @return bool * @throws ConfigException * @throws Exception */ public function isRunner(): bool { return $this->state->isRunner(); } /** * @param $daemon * @return Server */ public function setDaemon($daemon): static { if (!in_array($daemon, [0, 1])) { return $this; } $this->daemon = $daemon; return $this; } /** * @return HServer|SServer|WsServer|null */ #[Pure] public function getServer(): HServer|SServer|WsServer|null { return $this->manager->getServer(); } }