Files
2026-06-01 13:54:52 +08:00

328 lines
18 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 项目状态模型
<cite>
**本文引用的文件**
- [agent_project_runner_model.rs](file://crates/shared_types/src/model/agent_project_runner_model.rs)
- [agent_model.rs](file://crates/shared_types/src/model/agent_model.rs)
- [session_cache.rs](file://crates/agent_runner/src/service/session_cache.rs)
- [docker_container_agent.rs](file://crates/rcoder/src/proxy_agent/docker_container_agent.rs)
- [chat_handler.rs](file://crates/rcoder/src/handler/chat_handler.rs)
- [cleanup_task.rs](file://crates/rcoder/src/proxy_agent/cleanup_task.rs)
- [agent-abstraction-layer-design.md](file://specs/agent-abstraction-layer-design.md)
</cite>
## 目录
1. [简介](#简介)
2. [项目结构](#项目结构)
3. [核心组件](#核心组件)
4. [架构总览](#架构总览)
5. [详细组件分析](#详细组件分析)
6. [依赖关系分析](#依赖关系分析)
7. [性能考量](#性能考量)
8. [故障排查指南](#故障排查指南)
9. [结论](#结论)
## 简介
本文件围绕“项目状态模型”展开,重点解析 ProjectCoreState、ProjectExtendedState、ProjectState 以及 ProjectAndAgentInfo 等核心状态结构,阐明其字段语义、变更触发条件与同步机制;结合 agent_runner 与 rcoder 模块的实际用例,说明状态在 AI 代理生命周期中的流转;提供状态图示例与典型场景下的数据快照;解释线程安全处理方式(如 Arc、DashMap、Arc::make_mut、CancellationToken 等)与并发访问模式,并给出一致性保障措施。
## 项目结构
本仓库采用多 crate 分层组织,其中与“项目状态模型”直接相关的模块包括:
- shared_types跨模块共享的模型定义包含 ProjectCoreState、ProjectExtendedState、ProjectState、ProjectAndAgentInfo、AgentStatus 等。
- agent_runner会话缓存与消息推送涉及 session_id 与 Project 的映射管理。
- rcoder代理容器化启动、状态清理与生命周期管理涉及 Docker 容器生命周期与状态清理。
- specs抽象层设计文档描述 AgentStatus 的状态机与生命周期管理。
```mermaid
graph TB
subgraph "共享类型"
A["ProjectCoreState<br/>ProjectExtendedState<br/>ProjectState<br/>ProjectAndAgentInfo<br/>AgentStatus"]
end
subgraph "agent_runner"
B["SessionData<br/>SESSION_CACHE<br/>PROJECT_SESSION_MAP"]
C["push_session_update<br/>ensure_project_session"]
end
subgraph "rcoder"
D["Docker 容器代理启动<br/>start_docker_container_agent_service"]
E["清理任务<br/>cleanup_task"]
F["聊天处理器<br/>chat_handler"]
end
A --> B
B --> C
D --> E
F --> A
```
图表来源
- [agent_project_runner_model.rs](file://crates/shared_types/src/model/agent_project_runner_model.rs#L30-L189)
- [session_cache.rs](file://crates/agent_runner/src/service/session_cache.rs#L1-L120)
- [docker_container_agent.rs](file://crates/rcoder/src/proxy_agent/docker_container_agent.rs#L21-L130)
- [chat_handler.rs](file://crates/rcoder/src/handler/chat_handler.rs#L245-L270)
- [cleanup_task.rs](file://crates/rcoder/src/proxy_agent/cleanup_task.rs#L650-L720)
章节来源
- [agent_project_runner_model.rs](file://crates/shared_types/src/model/agent_project_runner_model.rs#L30-L189)
- [session_cache.rs](file://crates/agent_runner/src/service/session_cache.rs#L1-L120)
- [docker_container_agent.rs](file://crates/rcoder/src/proxy_agent/docker_container_agent.rs#L21-L130)
- [chat_handler.rs](file://crates/rcoder/src/handler/chat_handler.rs#L245-L270)
- [cleanup_task.rs](file://crates/rcoder/src/proxy_agent/cleanup_task.rs#L650-L720)
## 核心组件
本节聚焦“项目状态模型”的核心结构及其职责边界。
- ProjectCoreState
- 字段语义project_id项目唯一标识、session_id会话标识可选、last_activity最后活动时间、created_at创建时间
- 变更触发update_session 在创建会话时设置 session_id 并刷新 last_activityupdate_activity 仅刷新 last_activity。
- 访问模式:高频读写,适合通过 Arc 共享与写时复制更新。
- ProjectExtendedState
- 字段语义model_provider模型提供商配置可选、container容器信息可选、request_id当前活跃请求ID可选、statusAgent 服务状态,可选)。
- 变更触发update_from_request 批量更新容器、模型提供商与请求ID也可通过可变访问器逐项更新。
- 访问模式:相对稳定的扩展字段,适合 Arc 共享与写时复制更新。
- ProjectState
- 设计要点:将 core 与 extended 分离,分别使用 Arc 共享,提供 update_core/update_extended 方法,内部通过 Arc::make_mut 实现写时复制,避免不必要的深拷贝。
- 便捷访问器project_id、session_id、last_activity。
- ProjectAndAgentInfo
- 字段语义:在共享类型中提供向后兼容的结构,内部持有 ProjectState暴露与 ProjectState 对应的更新与访问方法。
- 变更触发update_session、update_activity、set_* 系列方法触发状态更新。
- AgentStatus
- 枚举值Active活跃、Idle空闲、Terminating正在终止
- 用途:表示 Agent 服务的运行状态,配合 last_activity、request_id 等字段共同反映代理生命周期。
章节来源
- [agent_project_runner_model.rs](file://crates/shared_types/src/model/agent_project_runner_model.rs#L30-L189)
- [agent_model.rs](file://crates/shared_types/src/model/agent_model.rs#L32-L41)
## 架构总览
下图展示“项目状态模型”在 rcoder 与 agent_runner 之间的交互,以及状态在代理生命周期中的流转。
```mermaid
sequenceDiagram
participant Client as "客户端"
participant RC as "rcoder 聊天处理器(chat_handler)"
participant PS as "ProjectAndAgentInfo(ProjectState)"
participant AR as "agent_runner 会话缓存(session_cache)"
participant DC as "Docker 容器代理(docker_container_agent)"
Client->>RC : "发起聊天/会话请求"
RC->>PS : "update_session(session_id)"
RC->>PS : "update_activity()"
RC->>AR : "push_session_update_with_project(project_id, session_id, notify)"
AR->>AR : "ensure_project_session(project_id, session_id)"
AR-->>RC : "推送消息到 SessionData"
RC->>DC : "启动容器化 Agent 服务(若需要)"
DC-->>RC : "返回容器信息与服务URL"
RC-->>Client : "返回会话状态与服务信息"
```
图表来源
- [chat_handler.rs](file://crates/rcoder/src/handler/chat_handler.rs#L245-L270)
- [session_cache.rs](file://crates/agent_runner/src/service/session_cache.rs#L259-L355)
- [docker_container_agent.rs](file://crates/rcoder/src/proxy_agent/docker_container_agent.rs#L21-L130)
- [agent_project_runner_model.rs](file://crates/shared_types/src/model/agent_project_runner_model.rs#L170-L202)
## 详细组件分析
### ProjectCoreState 与 ProjectExtendedState 的字段语义与更新流程
- 字段语义
- project_id项目唯一标识贯穿整个生命周期。
- session_id会话标识首次创建会话时设置用于区分不同会话。
- last_activity最近一次活动时间用于空闲检测与清理策略。
- created_at创建时间用于统计与审计。
- model_provider/container/request_id/status扩展状态承载容器、模型提供商、请求ID与服务状态等信息。
- 更新流程
- update_session设置 session_id 并刷新 last_activity。
- update_activity仅刷新 last_activity。
- update_from_request批量更新容器、模型提供商与请求ID。
- 写时复制更新
- ProjectState.update_core/update_extended 内部使用 Arc::make_mut在需要修改时才触发写时复制避免不必要的深拷贝。
```mermaid
flowchart TD
Start(["进入更新流程"]) --> CheckCore["是否更新核心状态?"]
CheckCore --> |是| MakeMutCore["Arc::make_mut(core)"]
MakeMutCore --> ApplyCore["应用更新: update_session/update_activity"]
CheckCore --> |否| CheckExtended["是否更新扩展状态?"]
CheckExtended --> |是| MakeMutExtended["Arc::make_mut(extended)"]
MakeMutExtended --> ApplyExtended["应用更新: update_from_request/set_*"]
CheckExtended --> |否| End(["结束"])
ApplyCore --> End
ApplyExtended --> End
```
图表来源
- [agent_project_runner_model.rs](file://crates/shared_types/src/model/agent_project_runner_model.rs#L117-L159)
章节来源
- [agent_project_runner_model.rs](file://crates/shared_types/src/model/agent_project_runner_model.rs#L30-L189)
### 会话映射与消息推送agent_runner
- SESSION_CACHE按 session_id 分组缓存会话消息,使用环形缓冲区与实时推送相结合的方式,减少内存占用并保证消息及时送达。
- PROJECT_SESSION_MAP确保一个 project_id 只对应一个活跃的 session_id。当 session_id 变化时,自动清理旧 session 的缓存数据。
- push_session_update/push_session_update_with_project将通知转换为统一消息并推送到 SessionDataensure_project_session 负责维护映射关系与清理旧数据。
```mermaid
sequenceDiagram
participant AR as "agent_runner"
participant PC as "PROJECT_SESSION_MAP"
participant SC as "SESSION_CACHE"
participant SD as "SessionData"
AR->>PC : "ensure_project_session(project_id, session_id)"
alt session_id 变化
PC-->>SC : "移除旧 session_id 对应的缓存"
end
AR->>SC : "push_session_update(session_id, notify)"
SC->>SD : "实时推送消息"
SD-->>AR : "推送完成"
```
图表来源
- [session_cache.rs](file://crates/agent_runner/src/service/session_cache.rs#L259-L355)
章节来源
- [session_cache.rs](file://crates/agent_runner/src/service/session_cache.rs#L1-L120)
- [session_cache.rs](file://crates/agent_runner/src/service/session_cache.rs#L259-L355)
### rcoder 中的状态更新与生命周期清理
- 聊天处理器chat_handler
- 在收到请求时,检查并更新项目会话状态:若 session_id 不同则更新会话并刷新 last_activity若相同则仅更新活动时间。
- 使用 Arc::make_mut 与写时复制更新,避免不必要的深拷贝。
- 清理任务cleanup_task
- 通过 DashMap 的 Entry API 原子性地移除项目到代理的映射,触发 AgentLifecycleGuard 的 Drop从而自动清理资源。
- 清理顺序:销毁 Docker 容器 -> 原子性移除项目映射 -> 原子性清理 sessions 映射 -> 输出清理完成日志。
- 超时保护:清理过程整体超时控制,防止阻塞。
```mermaid
sequenceDiagram
participant RT as "清理任务(cleanup_task)"
participant PM as "PROJECT_AND_AGENT_INFO_MAP"
participant SM as "sessions 映射"
participant DM as "DockerManager"
RT->>DM : "destroy_docker_container(project_id)"
DM-->>RT : "容器销毁完成"
RT->>PM : "原子性移除项目映射"
PM-->>RT : "返回 session_id"
RT->>SM : "原子性清理 sessions 映射(session_id)"
SM-->>RT : "清理完成"
RT-->>RT : "输出清理完成日志"
```
图表来源
- [cleanup_task.rs](file://crates/rcoder/src/proxy_agent/cleanup_task.rs#L650-L720)
- [docker_container_agent.rs](file://crates/rcoder/src/proxy_agent/docker_container_agent.rs#L733-L785)
章节来源
- [chat_handler.rs](file://crates/rcoder/src/handler/chat_handler.rs#L245-L270)
- [cleanup_task.rs](file://crates/rcoder/src/proxy_agent/cleanup_task.rs#L650-L720)
- [docker_container_agent.rs](file://crates/rcoder/src/proxy_agent/docker_container_agent.rs#L733-L785)
### AgentStatus 状态机与生命周期
- AgentStatus 枚举Active、Idle、Terminating。
- 状态切换时机(基于现有实现抽象):
- Active收到 Prompt 请求时。
- IdlePrompt 处理完成或被取消时。
- TerminatingAgent 停止过程中。
- AgentLifecycleGuard遵循 RAII 原则,当守卫被 drop 时自动清理资源;提供 graceful_stop、cancel、is_stopped、cancellation_token 等接口。
```mermaid
stateDiagram-v2
[*] --> Idle
Idle --> Active : "收到 Prompt 请求"
Active --> Idle : "任务完成/取消"
Active --> Terminating : "停止中"
Terminating --> [*]
```
图表来源
- [agent_model.rs](file://crates/shared_types/src/model/agent_model.rs#L32-L41)
- [agent-abstraction-layer-design.md](file://specs/agent-abstraction-layer-design.md#L1157-L1225)
章节来源
- [agent_model.rs](file://crates/shared_types/src/model/agent_model.rs#L32-L41)
- [agent-abstraction-layer-design.md](file://specs/agent-abstraction-layer-design.md#L1157-L1225)
### 线程安全与并发访问模式
- Arc 共享与写时复制
- ProjectState 将 core 与 extended 分离,分别使用 Arc 共享,通过 Arc::make_mut 在需要修改时才触发写时复制,降低锁竞争与内存拷贝成本。
- DashMap 原子性操作
- cleanup_task 使用 DashMap::entry API 原子性地移除映射,避免读写锁竞争,确保清理过程的一致性。
- CancellationToken
- AgentLifecycleGuard 使用 CancellationToken 实现非阻塞取消,优雅停止时先 cancel 再强制清理,保证资源释放与一致性。
- 会话连接管理
- SessionData 直接共享当前连接与取消令牌避免命令传递带来的额外开销close_current_connection 主动触发取消令牌并显式关闭发送端,确保接收端能及时感知连接关闭。
章节来源
- [agent_project_runner_model.rs](file://crates/shared_types/src/model/agent_project_runner_model.rs#L117-L159)
- [cleanup_task.rs](file://crates/rcoder/src/proxy_agent/cleanup_task.rs#L661-L704)
- [agent_model.rs](file://crates/shared_types/src/model/agent_model.rs#L218-L338)
- [session_cache.rs](file://crates/agent_runner/src/service/session_cache.rs#L1-L120)
## 依赖关系分析
- ProjectState 依赖于 chrono 时间类型与 serde 序列化能力,用于时间戳与持久化。
- ProjectAndAgentInfo 依赖于 shared_types 中的 AgentStatus、ModelProviderConfig 等类型,用于承载代理状态与模型配置。
- agent_runner 的 session_cache 依赖 DashMap、ringbuf、tokio channels 等并发与缓冲机制。
- rcoder 的清理任务依赖 DockerManager、DashMap、Tokio 定时器与超时控制。
```mermaid
graph LR
Shared["shared_types 模型"] --> Runner["agent_runner 会话缓存"]
Shared --> RC["rcoder 聊天处理器"]
Runner --> RC
RC --> Docker["DockerManager"]
RC --> Cleaner["清理任务"]
```
图表来源
- [agent_project_runner_model.rs](file://crates/shared_types/src/model/agent_project_runner_model.rs#L30-L189)
- [session_cache.rs](file://crates/agent_runner/src/service/session_cache.rs#L1-L120)
- [chat_handler.rs](file://crates/rcoder/src/handler/chat_handler.rs#L245-L270)
- [docker_container_agent.rs](file://crates/rcoder/src/proxy_agent/docker_container_agent.rs#L21-L130)
- [cleanup_task.rs](file://crates/rcoder/src/proxy_agent/cleanup_task.rs#L650-L720)
章节来源
- [agent_project_runner_model.rs](file://crates/shared_types/src/model/agent_project_runner_model.rs#L30-L189)
- [session_cache.rs](file://crates/agent_runner/src/service/session_cache.rs#L1-L120)
- [chat_handler.rs](file://crates/rcoder/src/handler/chat_handler.rs#L245-L270)
- [docker_container_agent.rs](file://crates/rcoder/src/proxy_agent/docker_container_agent.rs#L21-L130)
- [cleanup_task.rs](file://crates/rcoder/src/proxy_agent/cleanup_task.rs#L650-L720)
## 性能考量
- 写时复制Arc::make_mut在频繁读取、偶发更新的场景下显著降低锁竞争与内存拷贝成本。
- 会话缓存优化RingBuffer 缓冲与实时推送结合,既能保证消息及时性,又能控制内存占用。
- 原子性操作DashMap::entry API 在清理映射时避免读写锁竞争,提升清理吞吐。
- 取消令牌CancellationToken 非阻塞取消,配合优雅停止流程,减少资源泄漏与阻塞风险。
- 端口与网络优化:容器内部网络通信,避免宿主机端口映射与释放带来的额外开销。
## 故障排查指南
- 会话映射异常
- 现象:同一 project_id 出现多个活跃 session。
- 排查:确认 ensure_project_session 是否正确清理旧 session检查 PROJECT_SESSION_MAP 的原子性插入与移除。
- 参考路径:[session_cache.rs](file://crates/agent_runner/src/service/session_cache.rs#L282-L355)
- 清理任务超时或阻塞
- 现象:清理任务超时或长时间不结束。
- 排查:检查 destroy_docker_container 是否成功;确认清理流程中的超时保护与日志输出。
- 参考路径:[cleanup_task.rs](file://crates/rcoder/src/proxy_agent/cleanup_task.rs#L787-L836)
- 代理资源未释放
- 现象Agent 停止后仍占用资源。
- 排查:确认 AgentLifecycleGuard 的 Drop 是否触发;检查 cancellation_token 是否正确 cancel。
- 参考路径:[agent_model.rs](file://crates/shared_types/src/model/agent_model.rs#L340-L404)
- 会话连接无法断开
- 现象SSE 连接长时间不关闭。
- 排查:确认 close_current_connection 是否被调用;检查 CancellationToken 与发送端的显式关闭。
- 参考路径:[session_cache.rs](file://crates/agent_runner/src/service/session_cache.rs#L115-L140)
章节来源
- [session_cache.rs](file://crates/agent_runner/src/service/session_cache.rs#L282-L355)
- [cleanup_task.rs](file://crates/rcoder/src/proxy_agent/cleanup_task.rs#L787-L836)
- [agent_model.rs](file://crates/shared_types/src/model/agent_model.rs#L340-L404)
- [session_cache.rs](file://crates/agent_runner/src/service/session_cache.rs#L115-L140)
## 结论
本项目通过 ProjectCoreState/ProjectExtendedState/ProjectState 的分层设计,结合 Arc 共享与写时复制,实现了高性能、低锁争用的状态管理;借助 DashMap 原子性操作与 CancellationToken确保在高并发场景下的一致性与可靠性。agent_runner 的会话缓存与 rcoder 的清理任务共同构成了完整的生命周期管理闭环,覆盖从会话创建、消息推送、状态更新到资源清理的全链路。建议在新增状态字段时,遵循“核心小字段高频更新、扩展大字段低频更新”的设计原则,并优先使用写时复制与原子性操作,以获得最佳的性能与一致性表现。