兰 亭 墨 苑
期货 · 量化 · AI · 终身学习
首页
归档
编辑文章
标题 *
URL 别名 *
内容 *
(支持 Markdown 格式)
这次能够成功,核心原因在于解决了 **"多进程状态隔离"** 导致的信息不对称问题。 简单来说:**你启动 FSM 的那个进程,和负责处理按键的后台进程,其实是两个完全独立的"大脑"。** 这里是详细的复盘分析: ### 1. 之前为什么失败?(大脑失联) 当你执行 `tmux-fsm -enter` 时: 1. **CLI 进程启动**:它在自己的内存里把 `FSMActive` 设为 `true`,告诉 Tmux 设置 `@fsm_active=1`,然后**进程结束销毁**。 2. **后台 Daemon 进程**:它一直在后台运行。它**并没有**收到通知说"我们进入 FSM 模式了"。在它的内存里,`FSMActive` 仍然是 `false`。 **导致的结果:** * 当你按下 `h`,请求发给 Daemon。 * Daemon 处理完 `h` 后,代码走到了这里: ```go // 旧代码 if fsm.FSMActive { // Daemon 觉得:我内存里这是 false 啊 reconcileFSMState(...) // 所以这行救命代码被跳过了! } ``` * 与此同时,Tmux 处理完按键命令后,因为某些机制(比如焦点变化或命令结束),自动把键盘表切回了默认的 `root`。 * **Daemon 没有去纠正它**(因为它以为没在 FSM 模式)。 * 你按第二次键时,已经是 `root` 模式了,所以直接上屏。 --- ### 2. 这次为什么成功?(以 Tmux 为真理) 我们在 `main.go` 中去掉了 `if` 判断: ```go // 新代码 // 不管 Daemon 内存里怎么想,无条件执行状态核对 reconcileFSMState(actualClient) ``` **现在的流程是:** 1. 你按 `h`。 2. Daemon 处理完 `h`。 3. Daemon **被迫**去运行 `reconcileFSMState`。 4. `reconcileFSMState` 实际上是去问 Tmux: > "喂,Tmux,你的 `@fsm_active` 变量现在是 1 吗?" 5. Tmux 回答:"是的,之前那个 CLI 进程把它设为 1 了"。 6. `reconcileFSMState` 接着检查:"那你当前的 KeyTable 是 `fsm` 吗?" 7. 如果 Tmux 说:"哎呀,我不小心切回 `root` 了"。 8. `reconcileFSMState` 立即下令:**"不行!给我切回 `fsm`!"** ### 3. 那个空格的作用 (" @fsm_active") 之前 `enter_exit.go` 里多了一个空格:`backend.GlobalBackend.SetUserOption(" @fsm_active", "1")`。 * 这导致 Tmux 里设置了一个叫 `" @fsm_active"`(带空格)的变量。 * 但是 `reconcileFSMState` 读取的是 `"@fsm_active"`(不带空格)。 * **后果**:即使逻辑通了,Daemon 去读变量时读到的是空值(0),它会以为 FSM 已经关闭了,从而主动帮你退出了 FSM 模式。 ### 总结 这次成功的关键在于**确立了唯一的真理来源 (Source of Truth)**: * 不再相信 Go 程序的内存变量(因为进程是分离的)。 * **只相信 Tmux 的用户选项 (`@fsm_active`)**。 * 并且每次按键后,都强制根据 Tmux 的变量值来"锁死"键盘表状态。
配图 (可多选)
选择新图片文件或拖拽到此处
标签
更新文章
删除文章