Skip to content

fix(minecraft): retire failed engine before restarting - #366

Merged
Phantivia merged 3 commits into
Pal-AI-Lab:mainfrom
jcs130:fix/minecraft-engine-child-ownership-20261101
Nov 4, 2026
Merged

Phantivia merged 3 commits into
Pal-AI-Lab:mainfrom
jcs130:fix/minecraft-engine-child-ownership-20261101

Conversation

@jcs130

@jcs130 jcs130 commented Nov 1, 2026 •

Copy link
Copy Markdown

中文

Minecraft 引擎子进程的 init RPC 超时后,重连只丢掉了子进程引用,没有结束那个进程,接着 fork 一个新的。旧进程还连着服务器,和新进程抢同一个账号;它之后的消息和退出回调还会清掉新进程的状态。

现在 init 失败和停机走同一个 retireChild:先发 shutdown,等 5 秒,没退出就 kill 再等 5 秒,确认退出后才重试。消息和退出回调只认发出它们的那个子进程,已有受管子进程时 spawn 直接报错,有意结束的子进程不触发重启。代价:kill 之后 5 秒仍没退出时不再排重启,日志写「旧引擎没有退出,不再重启」,这个 World 停在没有引擎的状态,旧进程退出后要手动重启这个 World。

验证:pnpm test(287 个文件,5184 条通过,3 条跳过)与 pnpm run typecheck 通过;tests/worlds/minecraft/proxy.test.ts 的两条归属测试在改动前的 proxy.ts 上失败、改后通过。没有连真实 Minecraft 服务器验证;作者在 0.2.11 的直播部署上验证过,账号从两个抢占的引擎恢复成一个。

English

When the Minecraft engine's initialization RPC times out, a reconnect previously discarded the child reference without terminating that process. A replacement could then compete with the still-connected child for the same account. Late messages and exit callbacks from the old child could also clear the replacement's state.

Retire and await the exact owned child before retrying, bind callbacks to their originating process, and refuse concurrent spawns. Shutdown and initialization failure share one retirement promise; an intentional retirement cannot schedule another reconnect. This adds no server rules or alternate game loop.

Validation: complete official-main suite (5,184 passed, 3 skipped), TypeScript checks, and real fork/IPC regression tests. The same ownership fix was separately validated on the retained 0.2.11 consumer (5,197 passed, 3 skipped) and restored a live account from two competing children to one authenticated engine.

Phantivia and others added 2 commits November 4, 2026 13:26
- retireChild 发 shutdown 前不再判 connected:rpc 对未连接的子进程本来就立即拒绝,
  调用方传进来的总是当前子进程。
- waitExit 只补上 signalCode 的判断,其余回到原写法。
- init 失败的处理改用 .catch,init 请求体不再整段换行。
- 两条归属测试挪进 proxy.test.ts,复用 FakeHost,按该文件的排版写。

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- 重启时 spawn 失败而 this.child 仍在(旧引擎 kill 后 5 秒还没退出,或已有受管引擎),
  不会再排重启,日志原来照样写「继续重试」。

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@Phantivia
Phantivia merged commit e91dedf into Pal-AI-Lab:main Nov 4, 2026
3 checks passed
@Phantivia

Copy link
Copy Markdown
Member

谢谢修复,问题和改法都对。我们在你的分支上追加了两个提交:去掉了几处多余的判断(retireChild 发 shutdown 前的连接检查、waitExit 只留补上的 signalCode、init 失败改用 .catch),两条测试并进了 tests/worlds/minecraft/proxy.test.ts,并把「旧引擎没有退出、不再重启」那种情况的日志改准确了。PR 描述补了中文段。已合并,随下个版本发布。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants