This commit is contained in:
2026-06-24 20:17:55 +08:00
parent 0087115bdc
commit f099ca8402
+33 -1
View File
@@ -39,6 +39,14 @@ class Router
private static ?string $currentSourceFile = null; private static ?string $currentSourceFile = null;
/**
* 标记首次完整扫描是否已完成
* Master 进程中完成扫描后设为 trueWorker 通过 fork 继承此标记
* Worker 启动时检查此标记,避免重复执行全量 app 目录扫描导致 OOM
* @var bool
*/
private static bool $initialScanDone = false;
/** /**
* @param string $name * @param string $name
@@ -186,6 +194,17 @@ class Router
/** /**
* 扫描并构建路由表
*
* Master 进程:执行完整扫描(路由文件加载 + app 目录扫描 + DeferRegistry 注入)
* Worker 进程(首次启动):仅加载路由文件注册路由表,跳过全量 app 扫描
* Worker 进程(热重载):检测到文件变更时执行完整扫描流程
*
* 设计原因:
* - Master 已完成类加载和字节码编译,Worker 通过 fork 继承全部内存
* - Worker 重复执行 opcache_compile_file + invalidateClasses 不产生新信息
* - 在应用文件较多时(500+),每个 Worker 的全量扫描会消耗数百 MB 内存导致 OOM
*
* @throws * @throws
*/ */
public function scan_build_route(): void public function scan_build_route(): void
@@ -193,6 +212,20 @@ class Router
$coordinator = CoordinatorManager::utility(Coordinator::WORKER_START); $coordinator = CoordinatorManager::utility(Coordinator::WORKER_START);
$container = Kiri::getDi(); $container = Kiri::getDi();
$container->get(DataGrip::class)->reset(static::$type); $container->get(DataGrip::class)->reset(static::$type);
$changedFiles = $container->get(HotReloadState::class)->consume();
// Worker 首次启动(无变更文件 + Master 已完成扫描):仅加载路由,跳过全量 app 扫描
if (empty($changedFiles) && self::$initialScanDone) {
$this->read_dir_file(APP_PATH . 'routes');
$this->reset($container);
$coordinator->done();
return;
}
// 标记首次扫描完成(Master 首次启动或 Worker 热重载时执行到此)
self::$initialScanDone = true;
$scanner = $container->get(Kiri\Di\Scanner::class); $scanner = $container->get(Kiri\Di\Scanner::class);
$artifactState = $container->get(RouteArtifactState::class); $artifactState = $container->get(RouteArtifactState::class);
$scanConfig = array_merge( $scanConfig = array_merge(
@@ -201,7 +234,6 @@ class Router
); );
$scanner->setConfig($scanConfig); $scanner->setConfig($scanConfig);
$changedFiles = $container->get(HotReloadState::class)->consume();
$normalizedAppPath = str_replace('\\', '/', APP_PATH . 'app'); $normalizedAppPath = str_replace('\\', '/', APP_PATH . 'app');
$normalizedRoutePath = str_replace('\\', '/', APP_PATH . 'routes'); $normalizedRoutePath = str_replace('\\', '/', APP_PATH . 'routes');
$routeChanged = false; $routeChanged = false;