会话生命周期与 Journaling
会话生命周期与日志记录
相关源文件
本章引用的主要源码文件:
crates/jcode-config-types/Cargo.tomlcrates/jcode-selfdev-types/Cargo.tomlcrates/jcode-selfdev-types/src/lib.rscrates/jcode-session-types/Cargo.tomlcrates/jcode-session-types/src/lib.rssrc/agent.rssrc/main.rssrc/protocol.rssrc/server.rssrc/server/client_session_tests.rssrc/server/queue_tests.rssrc/server/startup_tests.rssrc/session.rssrc/session/model.rssrc/tool/debug_socket.rssrc/tool/session_search.rssrc/tool/session_search_tests.rssrc/tool/side_panel.rs
本文档描述了 jcode 的持久化模型,重点介绍会话如何创建、通过混合快照-日志记录系统演进,以及最终归档或恢复。该系统的设计旨在平衡高频更新(在工具执行期间)与数据完整性和性能。
会话创建与标识
会话是 jcode 中状态的主要单元。每个会话通过 Session::create_with_id src/session.rs:103 或 Session::create src/session.rs:160 生成的 session_id 唯一标识。
易记标识与金丝雀会话
- 易记标识:默认情况下,
jcode使用new_memorable_session_idsrc/session.rs:1创建人类可读的标识符(例如fox、oak),而不是原始 UUIDsrc/session.rs:111-113。 - 金丝雀会话:会话可以标记为
is_canarysrc/session.rs:104。这些会话用于测试代理的新构建版本src/session.rs:102-104。 - 自开发检测:系统通过检查环境快照中的
working_dirsrc/session.rs:110和is_selfdev标志crates/jcode-session-types/src/lib.rs:121,检测是否在"自开发"上下文中运行(例如代理修改自身源代码)。
会话状态枚举
SessionStatus 枚举跟踪会话的生命周期状态 crates/jcode-session-types/src/lib.rs:38-51:
| 状态 | 图标 | 描述 |
|---|---|---|
Active | ▶ | 当前正在运行并连接到服务器 crates/jcode-session-types/src/lib.rs:40。 |
Closed | ✓ | 由用户正常终止 crates/jcode-session-types/src/lib.rs:41。 |
Crashed | 💥 | 因恐慌或未处理错误而终止 crates/jcode-session-types/src/lib.rs:42。 |
Reloaded | 🔄 | 在二进制热重载期间保留状态 crates/jcode-session-types/src/lib.rs:45。 |
Compacted | 📦 | 历史记录已被摘要以节省 Token crates/jcode-session-types/src/lib.rs:46。 |
来源: src/session.rs:1-125、crates/jcode-session-types/src/lib.rs:38-85
混合持久化模型
jcode 采用混合持久化方法:完整快照(JSON)和增量日志(JSONL)。
1. 完整快照(会话::save)
Session 结构体被序列化为一个 JSON 文件,路径由 session_path(id) src/session.rs:42 返回。
- 原子写入:
Session::save通过写入文件系统确保数据完整性src/session.rs:155。 - 元数据:快照包含
compaction状态src/session.rs:76、provider_session_idsrc/session.rs:79和env_snapshotssrc/session.rs:134。
2. 日志记录(会话::append_journal)
为了避免每次添加单条消息时重写整个历史记录的 $O(N^2)$ 成本,jcode 将新事件追加到日志文件中 src/session.rs:12。
- MAX_SESSION_JOURNAL_BYTES:系统监控日志大小。当日志增长过大时,会触发完整快照以"压缩"日志
src/session.rs:41。 - PersistVectorMode:系统优化消息向量的持久化方式,跟踪哪些消息是新增的,哪些是已有的
src/session.rs:150。
数据流:持久化架构
下图展示了 Session 实体如何与存储层交互。
"会话持久化流程"
来源: src/session.rs:63-155、src/session.rs:38-42
会话加载与恢复
加载会话时,系统会将基础快照与任何增量日志条目进行协调。
1. 启动存根
为了提升 UI 性能(例如会话选择器),jcode 使用 SessionStartupStub src/session.rs:158。这使得 TUI 可以在不解析整个消息历史记录的情况下加载 title、created_at 和 status 等元数据 src/session.rs:158-168。
2. 崩溃检测与 PID 跟踪
- PID 注册:当服务器启动会话时,会调用
register_active_pidsrc/session.rs:9。 - 崩溃检测:
detect_crashed_sessions将会话文件中的last_pidsrc/session.rs:119与活动系统 PIDsrc/session.rs:19进行比较。如果 PID 已不存在但会话仍标记为Active,则会标记为崩溃crates/jcode-session-types/src/lib.rs:42。
代码到系统的映射:会话加载
"加载逻辑到代码实体"
来源: src/session.rs:8-21、src/session.rs:158-168、src/session.rs:42
重载与继续
jcode 的一个关键特性是能够在二进制重载期间(例如在自开发过程中)持久化状态。
重载恢复
重载后,服务器通过检查 Reloaded 状态来识别被中断的会话 src/server/client_session_tests.rs:2-3。
- 继续消息:
headless_reload_continuation_message生成一条指令,指示代理恢复执行src/server.rs:122。该指令指示大语言模型(LLM)从上次中断的位置继续执行src/server.rs:123-125。 - 无头恢复:如果无头会话的状态不是"已完成"或"失败",则会自动恢复
src/server.rs:118-120。
搜索集成
SessionSearchTool 允许代理在整个会话历史记录中执行检索增强生成(RAG)src/tool/session_search.rs:1-7。它会同时搜索快照和日志,以确保即使在下次完整保存之前也能看到最近的消息 src/tool/session_search.rs:6。
来源: src/server.rs:118-125、src/tool/session_search.rs:1-13、src/server/client_session_tests.rs:1-5