diff --git a/kiri-engine/FileListen/HotReload.php b/kiri-engine/FileListen/HotReload.php index a2b47b84..d9653723 100644 --- a/kiri-engine/FileListen/HotReload.php +++ b/kiri-engine/FileListen/HotReload.php @@ -25,212 +25,215 @@ class HotReload extends Command { - public bool $isReloading = false; - public bool $isReloadingOut = false; - public ?array $dirs = []; + public bool $isReloading = FALSE; + public bool $isReloadingOut = FALSE; + public ?array $dirs = []; - public int $events; + public int $events; - public int $int = -1; + public int $int = -1; - private ?Process $process = null; + private ?Process $process = NULL; - public Inotify|Scaner $driver; + public Inotify|Scaner $driver; - #[Inject(Logger::class)] - public Logger $logger; + #[Inject(Logger::class)] + public Logger $logger; - protected mixed $source = null; + protected mixed $source = NULL; - protected mixed $pipes = []; + protected mixed $pipes = []; - protected ?Coroutine\Channel $channel = null; + protected ?Coroutine\Channel $channel = NULL; - /** - */ - protected function configure() - { - $this->setName('sw:wather')->setDescription('server start') - ->addOption('daemon', null, InputOption::VALUE_OPTIONAL, "是否后台运行", "--front"); - } + /** + */ + protected function configure() + { + $this->setName('sw:wather')->setDescription('server start') + ->addOption('daemon', NULL, InputOption::VALUE_OPTIONAL, "是否后台运行", "--front"); + } - /** - * @throws ConfigException - * @throws \ReflectionException - * @throws Exception - */ - protected function initCore() - { - $this->dirs = Config::get('inotify', [APP_PATH . 'app']); - if (!extension_loaded('inotify')) { - $this->driver = Kiri::getDi()->make(Scaner::class, [$this->dirs, $this]); - } else { - $this->driver = Kiri::getDi()->make(Inotify::class, [$this->dirs, $this]); - } - $this->clearOtherService(); - $this->setProcessName(); - } + /** + * @throws ConfigException + * @throws \ReflectionException + * @throws Exception + */ + protected function initCore() + { + $this->dirs = Config::get('inotify', [APP_PATH . 'app']); + if (!extension_loaded('inotify')) { + $this->driver = Kiri::getDi()->make(Scaner::class, [$this->dirs, $this]); + } else { + $this->driver = Kiri::getDi()->make(Inotify::class, [$this->dirs, $this]); + } + $this->clearOtherService(); + $this->setProcessName(); + } - /** - * @throws ConfigException - */ - public function setProcessName() - { - swoole_async_set(['enable_coroutine' => false]); - set_error_handler([$this, 'errorHandler']); - if (Kiri::getPlatform()->isLinux()) { - swoole_set_process_name('[' . Config::get('id', 'sw service.') . '].sw:wather'); - } - } + /** + * @throws ConfigException + */ + public function setProcessName() + { + swoole_async_set(['enable_coroutine' => FALSE]); + set_error_handler([$this, 'errorHandler']); + if (Kiri::getPlatform()->isLinux()) { + swoole_set_process_name('[' . Config::get('id', 'sw service.') . '].sw:wather'); + } + } - /** - * @throws Exception - */ - public function clearOtherService() - { - if (file_exists(storage('.manager.pid'))) { - $pid = (int)file_get_contents(storage('.manager.pid')); - if ($pid > 0 && Process::kill($pid, 0)) { - Process::kill($pid, 15) && Process::wait(true); - } - } - file_put_contents(storage('.manager.pid'), getmypid()); - } + /** + * @throws Exception + */ + public function clearOtherService() + { + if (file_exists(storage('.manager.pid'))) { + $pid = (int)file_get_contents(storage('.manager.pid')); + if ($pid > 0 && Process::kill($pid, 0)) { + Process::kill($pid, 15) && Process::wait(TRUE); + } + } + file_put_contents(storage('.manager.pid'), getmypid()); + } - /** - * @throws Exception - */ - public function errorHandler() - { - $error = func_get_args(); + /** + * @throws Exception + */ + public function errorHandler() + { + $error = func_get_args(); - $path = ['file' => $error[2], 'line' => $error[3]]; + $path = ['file' => $error[2], 'line' => $error[3]]; - if ($error[0] === 0) { - $error[0] = 500; - } - $data = Json::to(500, $error[1], $path); + if ($error[0] === 0) { + $error[0] = 500; + } + $data = Json::to(500, $error[1], $path); - $this->logger->error($data, 'error'); - } + $this->logger->error($data, 'error'); + } - /** - * @param InputInterface $input - * @param OutputInterface $output - * @return int - * @throws ConfigException - * @throws Exception - */ - public function execute(InputInterface $input, OutputInterface $output): int - { - $this->initCore(); + /** + * @param InputInterface $input + * @param OutputInterface $output + * @return int + * @throws ConfigException + * @throws Exception + */ + public function execute(InputInterface $input, OutputInterface $output): int + { + $this->initCore(); - $this->trigger_reload(); - if ($input->getOption('') == '--daemon') { - Process::daemon(true, true); - } - Timer::tick(1000, fn() => $this->healthCheck()); + $this->trigger_reload(); + if ($input->getOption('') == '--daemon') { + Process::daemon(TRUE, TRUE); + } + Timer::tick(1000, fn() => $this->healthCheck()); - Process::signal(SIGTERM, [$this, 'onSignal']); - Process::signal(SIGKILL, [$this, 'onSignal']); + Process::signal(SIGTERM, [$this, 'onSignal']); + Process::signal(SIGKILL, [$this, 'onSignal']); - $this->driver->start(); - return 0; - } + $this->driver->start(); + return 0; + } - /** - * @throws Exception - */ - public function healthCheck() - { - $pid = (int)file_get_contents(storage('.swoole.pid')); - if (empty($pid)) { - $this->logger->warning('service is shutdown you need reload.'); - $this->trigger_reload(); - } else if (!Process::kill($pid, 0)) { - $this->logger->warning('service is shutdown you need reload.'); - $this->trigger_reload(); - } - } + /** + * @throws Exception + */ + public function healthCheck() + { + $pid = (int)file_get_contents(storage('.swoole.pid')); + if ($this->driver->isReloading) { + return; + } + if (empty($pid)) { + $this->logger->warning('service is shutdown you need reload.'); + $this->trigger_reload(); + } else if (!Process::kill($pid, 0)) { + $this->logger->warning('service is shutdown you need reload.'); + $this->trigger_reload(); + } + } - /** - * @param $data - * @throws Exception - */ - public function onSignal($data) - { - if (!$data) { - return; - } - Timer::clearAll(); - $this->driver->clear(); - $this->stopServer(); - $this->stopManager(); - while ($ret = Process::wait(true)) { - echo "PID={$ret['pid']}\n"; - sleep(1); - } - } + /** + * @param $data + * @throws Exception + */ + public function onSignal($data) + { + if (!$data) { + return; + } + Timer::clearAll(); + $this->driver->clear(); + $this->stopServer(); + $this->stopManager(); + while ($ret = Process::wait(TRUE)) { + echo "PID={$ret['pid']}\n"; + sleep(1); + } + } - /** - * @throws Exception - */ - protected function stopServer() - { - $pid = file_get_contents(storage('.swoole.pid')); - if (!empty($pid) && Process::kill($pid, 0)) { - Process::kill($pid, SIGTERM); - } - } + /** + * @throws Exception + */ + protected function stopServer() + { + $pid = file_get_contents(storage('.swoole.pid')); + if (!empty($pid) && Process::kill($pid, 0)) { + Process::kill($pid, SIGTERM); + } + } - /** - * - */ - protected function stopManager() - { - if ($this->process && Process::kill($this->process->pid, 0)) { - Process::kill($this->process->pid) && Process::wait(true); - } - } + /** + * + */ + protected function stopManager() + { + if ($this->process && Process::kill($this->process->pid, 0)) { + Process::kill($this->process->pid) && Process::wait(TRUE); + } + } - /** - * 重启 - * - * @throws Exception - */ - public function trigger_reload() - { - if ($this->int == 1) { - return; - } - $this->int = 1; - $this->logger->warning('change reload'); + /** + * 重启 + * + * @throws Exception + */ + public function trigger_reload() + { + if ($this->int == 1) { + return; + } + $this->int = 1; + $this->logger->warning('change reload'); - $this->stopServer(); - $this->stopManager(); + $this->stopServer(); + $this->stopManager(); - $this->process = new Process(function (Process $process) { - $process->exec(PHP_BINARY, [APP_PATH . "kiri.php", "sw:server", "restart"]); - }); + $this->process = new Process(function (Process $process) { + $process->exec(PHP_BINARY, [APP_PATH . "kiri.php", "sw:server", "restart"]); + }); - $this->process->start(); - $this->int = -1; - } + $this->process->start(); + $this->int = -1; + } } diff --git a/kiri-engine/FileListen/Inotify.php b/kiri-engine/FileListen/Inotify.php index 0a441ff2..b8c28098 100644 --- a/kiri-engine/FileListen/Inotify.php +++ b/kiri-engine/FileListen/Inotify.php @@ -15,7 +15,7 @@ class Inotify private array $watchFiles = []; - protected bool $isReloading = FALSE; + public bool $isReloading = FALSE; protected int $cid; diff --git a/kiri-engine/FileListen/Scaner.php b/kiri-engine/FileListen/Scaner.php index f337d3ff..43ca62e8 100644 --- a/kiri-engine/FileListen/Scaner.php +++ b/kiri-engine/FileListen/Scaner.php @@ -3,145 +3,147 @@ namespace Kiri\FileListen; use Exception; +use Swoole\Timer; class Scaner { - private array $md5Map = []; + private array $md5Map = []; - /** - * @param array $dirs - * @param HotReload $process - */ - public function __construct(protected array $dirs, public HotReload $process) - { - } + public bool $isReloading = FALSE; - /** - * @throws Exception - */ - public function start(): void - { - $this->loadDirs(); - $this->tick(); - } + /** + * @param array $dirs + * @param HotReload $process + */ + public function __construct(protected array $dirs, public HotReload $process) + { + } - /** - * @param bool $isReload - * @throws Exception - */ - private function loadDirs(bool $isReload = false) - { - foreach ($this->dirs as $value) { - if (is_bool($path = realpath($value))) { - continue; - } - - if (!is_dir($path)) continue; - - $this->loadByDir($path, $isReload); - } - } + /** + * @throws Exception + */ + public function start(): void + { + $this->loadDirs(); + $this->tick(); + } - /** - * @param $path - * @param bool $isReload - * @return void - * @throws Exception - */ - private function loadByDir($path, bool $isReload = false): void - { - if (!is_string($path)) { - return; - } - $path = rtrim($path, '/'); - foreach (glob(realpath($path) . '/*') as $value) { - if (is_dir($value)) { - $this->loadByDir($value, $isReload); - } - if (is_file($value)) { - if ($this->checkFile($value, $isReload)) { - $this->timerReload(); - break; - } - } - } - } + /** + * @param bool $isReload + * @throws Exception + */ + private function loadDirs(bool $isReload = FALSE) + { + foreach ($this->dirs as $value) { + if (is_bool($path = realpath($value))) { + continue; + } + + if (!is_dir($path)) continue; + + $this->loadByDir($path, $isReload); + } + } - /** - * @param $value - * @param $isReload - * @return bool - */ - private function checkFile($value, $isReload): bool - { - $md5 = md5($value); - $mTime = filectime($value); - if (!isset($this->md5Map[$md5])) { - if ($isReload) { - return true; - } - $this->md5Map[$md5] = $mTime; - } else { - if ($this->md5Map[$md5] != $mTime) { - if ($isReload) { - return true; - } - $this->md5Map[$md5] = $mTime; - } - } - return false; - } + /** + * @param $path + * @param bool $isReload + * @return void + * @throws Exception + */ + private function loadByDir($path, bool $isReload = FALSE): void + { + if (!is_string($path)) { + return; + } + $path = rtrim($path, '/'); + foreach (glob(realpath($path) . '/*') as $value) { + if (is_dir($value)) { + $this->loadByDir($value, $isReload); + } + if (is_file($value)) { + if ($this->checkFile($value, $isReload)) { + Timer::after(2000, fn() => $this->timerReload()); + $this->isReloading = TRUE; + break; + } + } + } + } - /** - * @throws Exception - */ - public function timerReload() - { - if ($this->process->isReloading) { - return; - } - $this->process->isReloading = true; - $this->process->trigger_reload(); - - $this->process->int = -1; - - $this->loadDirs(); - - $this->process->isReloading = FALSE; - $this->process->isReloadingOut = FALSE; - - $this->tick(); - } + /** + * @param $value + * @param $isReload + * @return bool + */ + private function checkFile($value, $isReload): bool + { + $md5 = md5($value); + $mTime = filectime($value); + if (!isset($this->md5Map[$md5])) { + if ($isReload) { + return TRUE; + } + $this->md5Map[$md5] = $mTime; + } else { + if ($this->md5Map[$md5] != $mTime) { + if ($isReload) { + return TRUE; + } + $this->md5Map[$md5] = $mTime; + } + } + return FALSE; + } - private bool $isStop = false; + /** + * @throws Exception + */ + public function timerReload() + { + $this->isReloading = TRUE; + $this->process->trigger_reload(); - public function clear() - { - $this->isStop = true; - } + $this->process->int = -1; + + $this->loadDirs(); + + $this->isReloading = FALSE; + $this->process->isReloadingOut = FALSE; + + $this->tick(); + } - /** - * @throws Exception - */ - public function tick() - { - if ($this->process->isReloading || $this->isStop) { - return; - } + private bool $isStop = FALSE; - $this->loadDirs(true); + public function clear() + { + $this->isStop = TRUE; + } - sleep(2); - $this->tick(); - } + /** + * @throws Exception + */ + public function tick() + { + if ($this->isReloading || $this->isStop) { + return; + } + + $this->loadDirs(TRUE); + + sleep(2); + + $this->tick(); + } }