diff --git a/docs/technical/README.md b/docs/technical/README.md index e96ef0a5..209e3bd5 100644 --- a/docs/technical/README.md +++ b/docs/technical/README.md @@ -5,6 +5,7 @@ ## 文档列表 - [RPG_AND_AGENT_CHAT_TRUE_SSE_STREAMING_2026-04-26.md](./RPG_AND_AGENT_CHAT_TRUE_SSE_STREAMING_2026-04-26.md):记录 RPG 运行时 NPC 聊天、RPG/自定义世界 Agent 与大鱼 Agent 从“拼完整 SSE 字符串后一次性返回”改为 `mpsc + Sse` 真流式输出的后端落地口径。 +- [SPACETIMEDB_START_SH_ROOT_OWNER_FALSE_POSITIVE_FIX_2026-04-27.md](./SPACETIMEDB_START_SH_ROOT_OWNER_FALSE_POSITIVE_FIX_2026-04-27.md):记录发布包 `start.sh` root-dir 占用检测把 `grep -F .../.spacetimedb` 误判为 SpacetimeDB 实例的根因、脚本修复和现场处理方式。 - [RPG_BATTLE_HEALTHBAR_AND_ACTION_PRESENTATION_FIX_2026-04-26.md](./RPG_BATTLE_HEALTHBAR_AND_ACTION_PRESENTATION_FIX_2026-04-26.md):记录 RPG 战斗血条安全锚点、服务端战斗回包前端短表现,以及 `battle_use_skill` 指定技能兜底结算的修复口径。 - [SPACETIMEDB_START_SH_PUBLISH_403_IDENTITY_FIX_2026-04-26.md](./SPACETIMEDB_START_SH_PUBLISH_403_IDENTITY_FIX_2026-04-26.md):记录发布包 `start.sh` 执行 `spacetime publish` 遇到 `403 Forbidden` 的身份根因、`.spacetimedb/` root-dir 隔离修复和排查步骤。 - [SPACETIMEDB_TABLE_CATALOG.md](./SPACETIMEDB_TABLE_CATALOG.md):持续维护当前 SpacetimeDB 表目录,按领域说明每张表的作用、字段结构、索引和常用 `spacetime sql` 查询模板。 diff --git a/docs/technical/RUST_LOCAL_AND_REMOTE_DEPLOYMENT_SCRIPTS_2026-04-22.md b/docs/technical/RUST_LOCAL_AND_REMOTE_DEPLOYMENT_SCRIPTS_2026-04-22.md index 4d2c9a01..fd67f88f 100644 --- a/docs/technical/RUST_LOCAL_AND_REMOTE_DEPLOYMENT_SCRIPTS_2026-04-22.md +++ b/docs/technical/RUST_LOCAL_AND_REMOTE_DEPLOYMENT_SCRIPTS_2026-04-22.md @@ -187,7 +187,7 @@ cd build/ 3. `start.sh` 只解析合法 `KEY=value` 环境行,支持不加引号、双引号和单引号;不执行复杂 shell 表达式,避免把环境文件变成脚本入口。 4. `start.sh` 默认不追加清理参数;只有显式执行 `./start.sh --clear-database` 才追加 `-c=on-conflict`,在 schema 冲突时清理旧模块数据后重发。 5. `start.sh` 使用 `spacetime publish --bin-path spacetime_module.wasm --yes` 发布当前包内 wasm;清库模式下会追加 `-c=on-conflict`,仅在 schema 冲突时删除旧模块数据。 -6. `start.sh` 会先复用已经按目标地址就绪的 SpacetimeDB;如果同一个 `.spacetimedb/` root-dir 已被其他未就绪实例占用,则按 dev 脚本逻辑输出占用进程并失败,避免误连错端口。 +6. `start.sh` 会先复用已经按目标地址就绪的 SpacetimeDB;如果同一个 `.spacetimedb/` root-dir 已被其他未就绪实例占用,则只输出命令名为 `spacetime` 或 `spacetimedb-cli` 且命令行包含当前 root-dir 的真实占用进程并失败,避免把排查用的 `grep` / `awk` 误判为 SpacetimeDB 实例。 7. 如果 `spacetime publish` 报 `403 Forbidden`,优先确认 `spacetime --root-dir ./.spacetimedb login show` 输出的身份是否有权更新目标库;`--clear-database` 不能绕过身份授权。 8. 当前脚本是单目录进程启动方案,不替代生产 systemd、Nginx、TLS、日志轮转与守护进程配置。 9. 如只需要本地生成发布包,可传 `--skip-upload` 跳过默认 scp 上传。 diff --git a/docs/technical/SPACETIMEDB_START_SH_ROOT_OWNER_FALSE_POSITIVE_FIX_2026-04-27.md b/docs/technical/SPACETIMEDB_START_SH_ROOT_OWNER_FALSE_POSITIVE_FIX_2026-04-27.md new file mode 100644 index 00000000..480477aa --- /dev/null +++ b/docs/technical/SPACETIMEDB_START_SH_ROOT_OWNER_FALSE_POSITIVE_FIX_2026-04-27.md @@ -0,0 +1,44 @@ +# start.sh root-dir 占用误报修复 + +日期:`2026-04-27` + +## 1. 问题 + +执行发布包内 `start.sh` 时,可能出现: + +```text +[start] 当前 root-dir 已被其他 SpacetimeDB 实例占用,无法再次启动。 +[start] 目标地址未就绪: http://127.0.0.1:3101 +root 2119763 2119760 0 09:06 pts/1 00:00:00 grep -F /var/lib/jenkins/deploy/Genarrative/.spacetimedb +``` + +此时执行 `sudo kill 2119763` 会返回 `No such process`。这是正常现象,因为该 pid 是一次性 `grep` 进程,日志打印出来时已经退出。 + +## 2. 根因 + +旧的占用检测逻辑使用: + +```bash +ps -ef | grep '[s]pacetime' | grep -F "${SPACETIME_ROOT_DIR}" +``` + +第一段 `grep '[s]pacetime'` 能避开自己的 `grep` 命令,但第二段 `grep -F "${SPACETIME_ROOT_DIR}"` 的命令行会包含 `.spacetimedb` 路径。由于 `.spacetimedb` 本身含有 `spacetime` 字符串,第一段过滤会把第二段 `grep` 也当成命中的进程,最终误判 root-dir 已被占用。 + +## 3. 修复 + +占用检测改为读取 `ps` 的 `comm` 与 `args` 字段,仅当同时满足以下条件时才输出占用进程: + +1. 命令名是 `spacetime` 或 `spacetimedb-cli`。 +2. 完整命令行包含当前 `SPACETIME_ROOT_DIR`。 + +这样既能定位真实持有同一 root-dir 的 SpacetimeDB 实例,也不会把 `grep`、`awk` 或其他排查命令误列为占用者。 + +## 4. 现场处理 + +如果日志里只看到 `grep -F .../.spacetimedb`,不要继续 kill 该 pid;它不是残留 SpacetimeDB。更新发布包中的 `start.sh` 后重新执行启动即可。 + +如果新日志列出 `spacetime` 或 `spacetimedb-cli`,再按实际场景处理: + +1. 如需复用,确认该进程监听的端口,并把 `GENARRATIVE_SPACETIME_PORT` 或 `GENARRATIVE_SPACETIME_SERVER_URL` 改为实际地址。 +2. 如需重启,先执行同目录 `./stop.sh`;若该进程不是本目录脚本启动,再按列出的真实 pid 停止。 +3. 不要删除 `.spacetimedb/` 来绕过身份或数据问题;涉及 403 身份错误时继续按 `SPACETIMEDB_START_SH_PUBLISH_403_IDENTITY_FIX_2026-04-26.md` 排查。 diff --git a/scripts/deploy-rust-remote.sh b/scripts/deploy-rust-remote.sh index c74e2d8c..24f6bb32 100644 --- a/scripts/deploy-rust-remote.sh +++ b/scripts/deploy-rust-remote.sh @@ -577,7 +577,24 @@ is_spacetime_ready() { describe_spacetime_root_owner() { if command -v ps >/dev/null 2>&1; then - ps -ef 2>/dev/null | grep '[s]pacetime' | grep -F "${SPACETIME_ROOT_DIR}" || true + ps -eo user=,pid=,ppid=,stat=,comm=,args= 2>/dev/null | awk -v root_dir="${SPACETIME_ROOT_DIR}" ' + { + user = $1 + pid = $2 + ppid = $3 + stat = $4 + command = $5 + args = $0 + sub(/^[[:space:]]*[^[:space:]]+[[:space:]]+[^[:space:]]+[[:space:]]+[^[:space:]]+[[:space:]]+[^[:space:]]+[[:space:]]+[^[:space:]]+[[:space:]]*/, "", args) + name = command + sub(/^.*\//, "", name) + + # 只认真实的 SpacetimeDB 启动进程,避免 .spacetimedb 路径让 grep/awk 自身误命中。 + if ((name == "spacetime" || name == "spacetimedb-cli") && index(args, root_dir) > 0) { + print user " " pid " " ppid " " stat " " name " " args + } + } + ' || true fi } diff --git a/scripts/dev-rust-stack.sh b/scripts/dev-rust-stack.sh index b64ebc08..7017f18b 100644 --- a/scripts/dev-rust-stack.sh +++ b/scripts/dev-rust-stack.sh @@ -124,7 +124,24 @@ Get-CimInstance Win32_Process | fi if command -v ps >/dev/null 2>&1; then - ps -ef 2>/dev/null | grep '[s]pacetime' | grep -F "${root_dir}" || true + ps -eo user=,pid=,ppid=,stat=,comm=,args= 2>/dev/null | awk -v root_dir="${root_dir}" ' + { + user = $1 + pid = $2 + ppid = $3 + stat = $4 + command = $5 + args = $0 + sub(/^[[:space:]]*[^[:space:]]+[[:space:]]+[^[:space:]]+[[:space:]]+[^[:space:]]+[[:space:]]+[^[:space:]]+[[:space:]]+[^[:space:]]+[[:space:]]*/, "", args) + name = command + sub(/^.*\//, "", name) + + # 只认真实的 SpacetimeDB 启动进程,避免 .spacetimedb 路径让 grep/awk 自身误命中。 + if ((name == "spacetime" || name == "spacetimedb-cli") && index(args, root_dir) > 0) { + print user " " pid " " ppid " " stat " " name " " args + } + } + ' || true fi }