Fix SpacetimeDB root-dir owner detection false positives
Some checks failed
CI / verify (push) Has been cancelled
Some checks failed
CI / verify (push) Has been cancelled
This commit is contained in:
@@ -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<Event>` 真流式输出的后端落地口径。
|
||||
- [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` 查询模板。
|
||||
|
||||
@@ -187,7 +187,7 @@ cd build/<timestamp>
|
||||
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 上传。
|
||||
|
||||
@@ -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` 排查。
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user