--- name: chongming description: > 用于 chongming-zenoh 项目的开发指导。当用户需要在此项目中添加新 Worker 插件、新增 RPC 端点、 修改配置驱动路由、开发前端页面、修改工具包、或进行构建部署时,使用此 skill 获取项目架构知识和开发规范。 keywords: - chongming - worker - plugin - rpc_method - zenoh - fastapi - 路由 - 配置 - 端点 - 插件开发 - 前端 - Vue --- # Chongming-Zenoh 项目开发指导 ## 项目总览 Chongming-Zenoh 是一个基于 **FastAPI + Zenoh + Vue 3** 的**配置驱动微服务网关平台**。 核心理念:通过 TOML 配置文件定义 RPC 端点,自动生成 Pydantic 模型和 FastAPI 路由, 底层通过 Zenoh 分布式消息协议进行 RPC 通信。 ### 项目五大部分 | 部分 | 路径 | 说明 | | --------------------- | -------------------- | -------------------------------------------------------------------------------- | | **chongming-core** | `src/chongming/` | 核心应用:FastAPI 工厂、Zenoh 集成、动态路由生成、Worker 管理 | | **chongming-web** | `src/chongming-web/` | Vue 3 前端:Element Plus UI、Pinia 状态管理、自动生成的 API 客户端 | | **chongming-utils** | `utils/` | 7 个子工具包:config, database, jwt(Rust), lock, password(Rust), request, worker | | **chongming-plugins** | `src/plugins/` | Worker 插件:auth, doubao, example,每个插件独立封装业务逻辑 | | **chongming-config** | `config/` | 配置文件:Zenoh 配置、Worker 路由 TOML 定义 | ## 核心架构与数据流 ``` 用户请求 → FastAPI 路由(自动生成)→ WorkerManager.call(subject, params) → Zenoh Query → Worker Queryable 回调 → 插件业务逻辑 → 响应 ``` ### 启动流程 ``` serve() → FastAPI lifespan: 1. setup_nanio() — 本地 S3 子进程 2. setup_s3() — boto3 S3 客户端 3. setup_zenoh() — Zenoh peer 会话 4. setup_worker_manager() — WorkerManager + 定期刷新 5. load_workers() — 动态 import 插件 6. register_routes() — 扫描 config/workers/ 生成路由 ``` ### 关键组件 - **`WorkerManager`** (`src/chongming/app/core/worker_manager.py`): Zenoh liveliness 发现 + 本地注册,负载均衡、超时重试、diskcache 缓存 - **`RouteGenerator`** (`src/chongming/app/core/route_generator.py`): 扫描 `config/workers//*.toml`,自动生成 FastAPI 端点 - **`chongming-worker`** (`utils/worker/`): Worker 框架,提供 `@rpc_method` 装饰器、`create_worker()` 运行时 --- ## 开发工作流 ### 一、添加新的 Worker 插件 创建新插件时需要以下步骤: #### 1. 创建插件目录结构 ``` src/plugins/<新插件名>/ ├── __init__.py # create_workers() 工厂 + cleanup() ├── global_var.py # 模块级全局变量 ├── router/ # RPC 端点实现 │ ├── __init__.py # 从各文件导入,__all__ 导出 │ └── <操作名>.py # 每个操作一个文件 └── models/ # 数据模型 ├── __init__.py # 模型导出 ├── pydantic.py # 自动生成(由 gen_models.py) └── <表名>.py # SQLModel ORM 模型(如需要) ``` #### 2. 添加 Worker 注册配置 在 `config/workers/config.toml` 的 `[[workers]]` 中添加: ```toml [[workers]] type = "<新插件名>" module = "plugins.<新插件名>" factory = "create_workers" cleanup = "cleanup" count = 3 ``` #### 3. 创建端点 TOML 配置文件 `config/workers/<新插件名>/config.toml`: ```toml [worker] defaults.timeout = 30 defaults.cacheable = false [worker.registration] router_prefix = "/" ``` `config/workers/<新插件名>/.toml`: ```toml [GET] # 或 [POST] cacheable = true summary = "操作描述" params = ["param1: str", "param2: int"] # 仅 GET auth_required = false [GET.response_model] # 或 [POST.response_model] field_name = { type = "str", required = true } another_field = { type = "int", default = 0 } ``` #### 4. 生成 Pydantic 模型 ```bash uv run python -m chongming.scripts.gen_models ``` 这会根据 TOML 配置自动生成 `src/plugins/<新插件名>/models/pydantic.py`,包含请求和响应的 Pydantic 模型类。 #### 5. 编写 RPC 端点实现 (`router/<操作>.py`) ```python # src/plugins//router/.py from chongming_worker.decorators import rpc_method from ..models.pydantic import SomeRequest, SomeResponse @rpc_method(subject=".", method="GET", response_model=SomeResponse) async def my_operation(request: SomeRequest) -> SomeResponse: """业务逻辑实现""" # 使用 global_var 中的资源 result = await do_something(request) return SomeResponse(result=result) ``` **注意**: 此处的 `SomeRequest` / `SomeResponse` 等 Pydantic 模型必须来自步骤 4 生成的 `models/pydantic.py`。编写端点代码前必须先完成模型生成。 #### 6. 编写 `router/__init__.py` ```python # src/plugins//router/__init__.py from . import operation1, operation2 __all__ = ["operation1", "operation2"] ``` #### 7. 编写 `__init__.py` 工厂函数 ```python # src/plugins//__init__.py from chongming_worker.runtime import create_workers as _create_workers def create_workers(session, config, count, worker_manager): """插件入口:初始化全局资源,创建 Worker 副本""" from . import router # 触发 @rpc_method 注册 from .global_var import set_db, set_client # 设置全局变量 # 初始化数据库、客户端等... _create_workers(session, config, count, worker_manager) async def cleanup(worker_manager): """清理资源""" # 关闭连接、清理缓存等... ``` ### 二、为现有插件添加新 RPC 端点 1. 在 `config/workers/<插件名>/` 下创建 `<新操作>.toml`,定义端点参数和响应模型 2. 运行 `uv run python -m chongming.scripts.gen_models` 生成 Pydantic 模型 3. 在 `src/plugins/<插件名>/router/` 下创建 `<新操作>.py`,引用生成的模型编写业务逻辑 4. 更新 `src/plugins/<插件名>/router/__init__.py`,添加 import 5. 重启服务 ### 三、修改配置驱动路由 - **修改路由前缀**: 编辑 `config/workers/<插件名>/config.toml` 的 `router_prefix` - **添加/修改端点参数**: 编辑 `<操作>.toml`,然后重新生成模型 - **调整 Worker 副本数**: 编辑 `config/workers/config.toml` 的 `count` ### 四、前端开发 (`chongming-web`) 位于 `src/chongming-web/`: - **UI 框架**: Element Plus - **状态管理**: Pinia - **路由**: Vue Router (Hash History) - **API 调用**: `src/api/generated/` 中由 `@hey-api/openapi-ts` 自动生成的类型安全客户端 添加新页面流程: 1. 在 `src/views/` 创建 Vue 组件 2. 在 `src/router/index.ts` 添加路由 3. 在 `src/App.vue` 导航菜单添加入口 4. 如需要,在 `src/api/generated/sdk.gen.ts` 添加或重新生成 API 调用函数 ### 五、工具包开发 (`chongming-utils`) 每个 `utils//` 下的子包是独立的 Python 包,有各自的 `pyproject.toml`: - **config**: 加载 `config.toml`,TypedDict 配置结构 - **database**: 异步 SQLite (aiosqlite + SQLModel) - **jwt**: Rust 实现的 JWT 编码/验证 (maturin + jsonwebtoken) - **lock**: 基于 diskcache 的跨进程分布式锁 - **password**: Rust 实现的 Argon2id 密码哈希 - **request**: Zenoh 客户端封装 - **worker**: Worker 框架核心(`@rpc_method` 装饰器、`create_worker` 运行时) 修改工具包后需要重新安装: ```bash uv pip install -e utils/ ``` ## 核心约定与规范 ### 命名约定 - **插件名**: 小写下划线,如 `doubao`, `auth`, `example` - **操作名**: 小写下划线,如 `analyze`, `add`, `count` - **Zenoh subject**: `<插件名>.<操作名>`,如 `example.add`, `doubao.analyze` - **TOML 文件名**: 与操作名一致,如 `analyze.toml`, `add.toml` - **Python 文件名**: 与操作名一致,如 `analyze.py`, `add.py` ### 装饰器使用 ```python @rpc_method( subject="plugin.operation", # Zenoh 主题 (必需) method="GET", # HTTP 方法: GET 或 POST response_model=ResponseCls, # Pydantic 响应模型 ) async def handler(request: RequestCls) -> ResponseCls: ... ``` - GET 端点:参数通过 URL query string 传递,在 TOML 中用 `params` 定义 - POST 端点:参数通过 JSON body 传递,自动绑定到 Pydantic 请求模型 ### 全局变量模式 每个插件通过 `global_var.py` 管理模块级共享资源: ```python # global_var.py db: Database = None def set_db(database: Database): global db db = database ``` ### TOML 配置字段说明 | 字段 | 位置 | 说明 | | -------------------- | --------------------- | ---------------------------------- | | `count` | `workers/config.toml` | Worker 副本数 | | `router_prefix` | `<插件>/config.toml` | API 路由前缀 | | `defaults.timeout` | `<插件>/config.toml` | 默认超时 (秒) | | `defaults.cacheable` | `<插件>/config.toml` | 是否缓存 RPC 结果 | | `params` | `<操作>.toml` `[GET]` | GET 参数列表 (`"name: type"` 格式) | | `auth_required` | `<操作>.toml` | 是否需要 JWT 鉴权 | | `cacheable` | `<操作>.toml` | 端点是否可缓存 | | `summary` | `<操作>.toml` | 端点描述 (用于 OpenAPI docs) | ## 常用命令 ```bash # 开发启动 uv run serve # 生成 Pydantic 模型 uv run python -m chongming.scripts.gen_models # 构建 uv run python -m chongming.scripts.build # 安装/更新工具包子包 uv pip install -e utils/ # 前端开发 cd src/chongming-web && npm run dev ``` ## 注意事项 1. **修改 TOML 配置后必须重新生成模型**: `uv run python -m chongming.scripts.gen_models` 2. **新增插件后需要在 `config/workers/config.toml` 注册**: 否则插件不会被加载 3. **Rust 工具包 (jwt, password) 需要 maturin**: 通过 `uv run maturin develop --release -m utils//Cargo.toml` 编译 4. **插件间隔离**: 每个插件有独立的全局变量,不要跨插件直接引用 5. **数据库路径约定**: SQLite 数据库文件放在 `data/storage/chongming/` 下 6. **日志**: 使用标准 `logging.getLogger(__name__)`,核心已配置 ANSI 颜色格式化器