Refactor local dev stack scheduler

This commit is contained in:
kdletters
2026-05-15 09:37:08 +08:00
parent 0152f9bd67
commit 7a3b137565
20 changed files with 2393 additions and 2088 deletions

View File

@@ -146,8 +146,8 @@ metadata:
```bash
# 只看后台页面 + api-server不要求 SpacetimeDB 真实数据
npm run api-server
npm run admin-web:dev -- --host 127.0.0.1
npm run dev:api-server
npm run dev:admin-web -- --admin-web-host 127.0.0.1
# 完整 Rust 本地栈SpacetimeDB + 发布模块 + api-server + 主站 + 后台
npm run dev
@@ -155,19 +155,19 @@ npm run dev
验证地址通常为:
- `npm run api-server` 单独启动api-server `http://127.0.0.1:3100/healthz`,后台前端 `http://127.0.0.1:5173/admin/`
- `npm run dev:api-server` 单独启动api-server 默认 `http://127.0.0.1:8082/healthz`,后台前端默认 `http://127.0.0.1:3102/admin/`
- `npm run dev` 完整栈SpacetimeDB `http://127.0.0.1:3101/v1/ping`api-server `http://127.0.0.1:8082/healthz`,主站 `http://127.0.0.1:3000/`,后台 `http://127.0.0.1:3102/admin/`
注意:
- `npm run api-server` 首次启动可能先编译 Rust后台进程短时间内无完整日志等待编译完成后再查端口。
- 不要默认用 `3200` 验证 api-server当前脚本环境变量常见为 `GENARRATIVE_API_PORT=3100`。不确定时 `ss -ltnp | grep api-server` 或读取进程环境核对,敏感值输出必须打码。
- `npm run dev:api-server` 首次启动可能先编译 Rust后台进程短时间内无完整日志等待编译完成后再查端口。
- 不要默认用 `3200` 验证 api-server当前脚本默认 `GENARRATIVE_API_PORT=8082`,但会按端口占用情况漂移。不确定时 `[dev] api-server:` 日志为准,或读取进程环境核对,敏感值输出必须打码。
- `admin-web``/` 可能返回 302 跳转到 `/admin/`;验证前端时直接请求 `/admin/`
- api-server 启动日志中 SpacetimeDB `127.0.0.1:3101` 连接被拒绝,不一定代表 api-server 没起来;只表示依赖的本地 SpacetimeDB 不可用。后台中需要读 SpacetimeDB 的页面(如埋点明细、表查询)要等 SpacetimeDB 可用后才能返回真实数据。
- `npm run dev` 依赖 `spacetime` CLI先用 `command -v spacetime && spacetime --version` 确认可用。
- 本地和人工排障不再使用 `spacetime --root-dir`。如果看到 `bin/current/spacetimedb-cli` 缺失类错误,优先确认是否仍在运行旧脚本或旧发布包;本地开发应使用 `npm run dev` / `npm run dev:rust`,通过项目脚本和 `--data-dir` 隔离 SpacetimeDB 数据目录,不再把用户级 SpacetimeDB 安装同步到项目目录。
- 本地和人工排障不再使用 `spacetime --root-dir`。如果看到 `bin/current/spacetimedb-cli` 缺失类错误,优先确认是否仍在运行旧脚本或旧发布包;本地开发应使用 `npm run dev` / `npm run dev:spacetime`,通过项目脚本和 `--data-dir` 隔离 SpacetimeDB 数据目录,不再把用户级 SpacetimeDB 安装同步到项目目录。
- `scripts/dev-rust-stack.sh` 默认 `api timeout: 300s`. 合并 master 后首次 Rust 依赖/工作区重编译可能超过 300s,导致完整 `npm run dev` 在 api-server 就绪前超时并回收 SpacetimeDB。先让 Rust 编译完成,或临时用 `bash scripts/dev-rust-stack.sh --skip-spacetime --skip-publish --api-timeout-seconds 900` 预热 api-server 编译;之后再重新跑完整 `npm run dev`
- `scripts/dev.mjs` 默认 `api timeout: 600s`. 合并 master 后首次 Rust 依赖/工作区重编译可能超过默认等待窗口,导致完整 `npm run dev` 在 api-server 就绪前超时并回收 SpacetimeDB。先让 Rust 编译完成,或临时用 `npm run dev:api-server -- --api-timeout-seconds 900` 预热 api-server 编译;之后再重新跑完整 `npm run dev`
- 用户贴出的 Hermes background watch 通知可能来自已退出的旧 session。先用 `process poll` 查该 session 状态,再判断是否需要处理;不要把旧失败误判成当前服务失败。
## 测试与验证
@@ -222,4 +222,4 @@ npm install
- `references/spacetimedb-http-sql-sats-display.md`:通过 HTTP SQL 读取 private table 时enum / Option / Timestamp 的 SATS 原始 rows 如何转换为后台列表、详情和 Excel 可读值。
- `references/daily-login-tracking-trigger-points.md`:排查后台 `daily_login` 埋点为何不是登录接口写入,而是任务中心读取/领奖兜底写入的触发点记录。
- `references/daily-login-auth-closure.md`将方案A拆出的每日登录埋点入口接入真实认证成功链路时的推荐接入点、非阻断语义、测试和提交注意事项。
- `references/dev-rust-stack-startup-2026-05-08.md``npm run dev` / `scripts/dev-rust-stack.sh` 在 WSL/Linux 下改用用户级 SpacetimeDB CLI、项目数据目录和显式 publish server避免项目级 `--root-dir` 与冷编译超时的修复记录。
- `references/dev-rust-stack-startup-2026-05-08.md``npm run dev` / `scripts/dev.mjs` 在 WSL/Linux 下改用用户级 SpacetimeDB CLI、项目数据目录和显式 publish server避免项目级 `--root-dir` 与冷编译超时的修复记录。

View File

@@ -1,7 +1,7 @@
---
name: genarrative-dev-stack-port-routing
short_description: 修改 Genarrative 本地 dev 启动端口、代理目标、端口冲突处理时使用。
description: 在 Genarrative 中修改 npm run dev / npm run dev:rust / npm run dev:web 的本地启动端口、端口可用性探测、端口漂移、SpacetimeDB publish server、api-server 环境变量、Vite 代理目标和后台 admin-web 启动串联时使用。
description: 在 Genarrative 中修改 npm run dev / dev:spacetime / dev:api-server / dev:web / dev:admin-web 的本地启动端口、端口可用性探测、端口漂移、SpacetimeDB publish server、api-server 环境变量、Vite 代理目标和后台 admin-web 启动串联时使用。
version: 1.0.0
author: Hermes Agent
license: MIT
@@ -13,11 +13,11 @@ metadata:
# Genarrative 本地 dev 启动端口与代理目标串联流程
用于维护 Genarrative 本地开发栈启动脚本,重点覆盖 `npm run dev` / `npm run dev:rust` / `npm run dev:web` 的端口检查、端口漂移和后续流程目标传递。
用于维护 Genarrative 本地开发栈启动脚本,重点覆盖 `npm run dev` 与四个 `dev:*` 单模块命令的端口检查、端口漂移和后续流程目标传递。
## 适用场景
- 修改 `scripts/dev-rust-stack.sh``scripts/dev-web-rust.mjs``scripts/dev-stack-port-utils.mjs`
- 修改 `scripts/dev.mjs``scripts/dev-utils.mjs``scripts/dev-stack-port-utils.mjs`
- 处理 `3000``3101``3102``8082` 等端口被占用导致本地开发栈启动失败。
- 排查 Vite 代理仍指向旧 api-server 端口、前端打开了旧 dev server、后台代理错配。
- 调整 SpacetimeDB standalone、publish、Rust `api-server`、主站 Vite、后台 Vite 的启动顺序。
@@ -37,23 +37,21 @@ metadata:
## 实现入口
- `package.json`
- `dev``dev:rust`:执行 `node scripts/run-bash-script.mjs scripts/dev-rust-stack.sh`
- `dev:web`:执行 `node scripts/dev-web-rust.mjs`
- `dev`:执行 `node scripts/dev.mjs`,启动完整四模块
- `dev:spacetime` / `dev:api-server` / `dev:web` / `dev:admin-web`:执行 `node scripts/dev.mjs <module>`
- `scripts/dev-stack-port-utils.mjs`
- `isPortAvailable(...)`:探测端口是否可监听。
- `findAvailablePort(...)`:从优先端口向后寻找可用端口,`0` 表示申请临时端口。
- `resolveDevStackPorts(...)`:一次性解析 SpacetimeDB、api-server、主站 Vite、后台 Vite 端口,并避免本次解析结果互相冲突。
- CLI 模式:`node scripts/dev-stack-port-utils.mjs resolve-dev-stack spacetime:127.0.0.1:3101 api:127.0.0.1:8082 web:0.0.0.0:3000 adminWeb:127.0.0.1:3102`
- `scripts/dev-rust-stack.sh`
- 解析 CLI 参数后,先计算 `API_TARGET_HOST``ADMIN_WEB_TARGET_HOST`
- 调用 `resolve_dev_stack_ports` 覆盖 `SPACETIME_PORT``API_PORT``WEB_PORT``ADMIN_WEB_PORT`
- 再构造 `SPACETIME_SERVER``RUST_SERVER_TARGET`
- `scripts/dev-web-rust.mjs`
- 单独启动主站前端时,也先用 `findAvailablePort` 检查 `WEB_PORT` / 默认 `3000`
- `scripts/dev.mjs`
- 解析 CLI 参数后统一计算 client host、端口、`SPACETIME_SERVER``RUST_SERVER_TARGET`
- 完整栈按 SpacetimeDB、publish、api-server、主站 Vite、后台 Vite 顺序启动
- 单模块命令复用同一套参数和 env 解析
## 必须保持的传递链路
`npm run dev` / `npm run dev:rust` 中端口解析后,必须同步到以下位置:
`npm run dev` 和四个 `dev:*` 单模块命令中端口解析后,必须同步到以下位置:
1. SpacetimeDB 启动:`spacetime start --listen-addr "${SPACETIME_HOST}:${SPACETIME_PORT}"`
2. SpacetimeDB 发布:`spacetime publish ... --server "${SPACETIME_SERVER}"`
@@ -61,7 +59,7 @@ metadata:
4. api-server 健康检查:`wait_for_api_server "${RUST_SERVER_TARGET}/healthz" ...`
5. 主站 Vite`RUST_SERVER_TARGET``GENARRATIVE_RUNTIME_SERVER_TARGET``ADMIN_WEB_TARGET``ADMIN_WEB_PORT``--port=${WEB_PORT}``--host=${WEB_HOST}`
6. 后台 Vite`ADMIN_API_TARGET``GENARRATIVE_API_TARGET``GENARRATIVE_API_PORT``--port=${ADMIN_WEB_PORT}`
7. 控制台日志:`[dev:ports]``[dev:rust] web/admin web/rust api/spacetime` 必须显示最终实际地址。
7. 控制台日志:`[dev:ports]``[dev] web/admin web/api-server/spacetime` 必须显示最终实际地址。
如果只改了其中一段,通常会出现:浏览器打开的前端可用,但 `/api/*` 代理到旧端口;后台页面可用但后台 API 失败SpacetimeDB 启动在新端口但 publish 仍发往旧端口。
@@ -69,17 +67,13 @@ metadata:
1. 先读当前脚本和文档:
- `scripts/dev-stack-port-utils.mjs`
- `scripts/dev-rust-stack.sh`
- `scripts/dev-web-rust.mjs`
- `docs/【开发运维】本地开发验证与生产运维-2026-05-15.md`
- `scripts/dev.mjs`
- `scripts/dev-utils.mjs`
- `docs/technical/RUST_LOCAL_AND_REMOTE_DEPLOYMENT_SCRIPTS_2026-04-22.md`
- `.hermes/shared-memory/pitfalls.md`
2. 优先改公共端口工具,不要把端口探测逻辑复制到多个脚本。
3. 对 Bash 脚本只做局部补丁,避免整文件重写导致中文注释或换行大面积变化
4. 修改 `dev-rust-stack.sh` 时确认变量顺序:
- 先有 `REPO_ROOT`
- 再计算 `API_TARGET_HOST` / `ADMIN_WEB_TARGET_HOST`
- 再调用端口解析工具。
- 再构造 `SPACETIME_SERVER` / `RUST_SERVER_TARGET`
3. 修改 `scripts/dev.mjs` 时确认变量顺序:先解析参数和端口,再构造 `SPACETIME_SERVER` / `RUST_SERVER_TARGET`,最后启动对应 service
4. 修改 watch 时保持模块边界SpacetimeDB 只监听 `spacetime-module` 且改动后重新 publish不重启 standalone 宿主api-server 排除 `spacetime-module`web/admin-web 源码变化交给 Vite 自身 HMR外层调度器不要再监听前端目录重启 Vite。
5. 修改 `dev:web` 时不要自动改后端目标策略;`dev:web` 只负责主站 Vite 端口可用性与已有后端目标选择。
6. 同步更新技术文档和团队共享记忆。
@@ -88,7 +82,7 @@ metadata:
最小验证:
```bash
bash -n scripts/dev-rust-stack.sh
node --check scripts/dev.mjs
npm run test -- scripts/dev-stack-port-utils.test.ts
npm run check:encoding
node scripts/dev-stack-port-utils.mjs resolve-dev-stack spacetime:127.0.0.1:0 api:127.0.0.1:0 web:0.0.0.0:0 adminWeb:127.0.0.1:0
@@ -101,8 +95,8 @@ node scripts/dev-stack-port-utils.mjs resolve-dev-stack spacetime:127.0.0.1:0 ap
3. 调用 `resolveDevStackPorts`,断言四个结果互不相同。
4. 如果实际启动完整栈,观察控制台:
- `[dev:ports] ... 不可用,改用 ...`
- `[dev:rust] rust api: http://...:<actual-api-port>`
- `[dev:rust] spacetime: http://...:<actual-spacetime-port>`
- `[dev] api-server: http://...:<actual-api-port>`
- `[dev] spacetime: http://...:<actual-spacetime-port>`
- 主站和后台 Vite 启动端口与日志一致。
完整启动属于长驻进程。需要 smoke 时用 background 方式启动,并另开命令检查 `/healthz``/v1/ping` 和页面端口;不要等待 `npm run dev` 自然退出。
@@ -119,9 +113,9 @@ node scripts/dev-stack-port-utils.mjs resolve-dev-stack spacetime:127.0.0.1:0 ap
## 验收清单
- [ ] 端口工具有测试覆盖端口被占用和多端口互斥解析。
- [ ] `dev-rust-stack.sh` 通过 `bash -n`
- [ ] `npm run dev` / `npm run dev:rust` 的 SpacetimeDB、publish、api-server、主站 Vite、后台 Vite 都使用实际端口。
- [ ] `scripts/dev.mjs` 通过 `node --check`
- [ ] `npm run dev` 的 SpacetimeDB、publish、api-server、主站 Vite、后台 Vite 都使用实际端口。
- [ ] `npm run dev:web` 在主站端口不可用时能切换到可用端口。
- [ ] 文档同步更新 `docs/【开发运维】本地开发验证与生产运维-2026-05-15.md`
- [ ] 文档同步更新 `docs/technical/RUST_LOCAL_AND_REMOTE_DEPLOYMENT_SCRIPTS_2026-04-22.md`
- [ ] 长期踩坑同步更新 `.hermes/shared-memory/pitfalls.md`
- [ ] 修改中文文件后运行 `npm run check:encoding`