架构
概述
Thurgio 组织为 23 个 crate(thurgio-bench 为仅开发用的基准 crate,fuzz 为 workspace 成员,共 23 crates/* + fuzz),分布在 5 层中,具有严格的依赖方向。上层依赖于下层的抽象;下层从不依赖上层。
关于详细的接口合约和 ADR,请参阅 design/architecture-detailed.md 和 design/technical-decision.md。
接口层 (thurgio-cli, thurgio-server)
↓ (仅通过 app facade)
应用层 (thurgio-app, thurgio-app-update, thurgio-app-build, thurgio-app-state, thurgio-event)
↓
数据访问层 (thurgio-db)
↓
领域层 (thurgio-domain, thurgio-proxy, thurgio-proxy-singbox, thurgio-formats,
thurgio-filter, thurgio-renderer, thurgio-renderer-api, thurgio-script,
thurgio-config, thurgio-config-api)
↓
基础设施层 (thurgio-types, thurgio-infra, thurgio-request, thurgio-test-utils)
基础设施层
thurgio-types— 基础类型(Ar<T>、Rw<T>、Fields、ThurgioError+ErrorKind、Udp、UpdateState)与包身份标识(identity模块:NAME、VERSION、GIT_BUILD、get_version(),由build.rs嵌入git describe快照)。thurgio-infra— 日志初始化(init_logger)、请求追踪(request_tracing)、HTTP 客户端工厂(create_client)、熔断器(CircuitBreaker/CircuitBreakerPool)、指标抽象(MetricsRecorder/NoopMetrics)、set_root_dir工作目录管理。thurgio-request— HTTP 响应包装(Res)、来源抽象(Source:File/Url)、AppHttpClienttrait。thurgio-event— 进程内部事件总线(EventBus、DomainEvent、EventHandler、Envelope)。使用tokio::sync::broadcast,慢订阅者会丢失事件。thurgio-test-utils— 集成测试工具(测试应用工厂、测试配置构建器)。
领域层
thurgio-domain— 核心业务类型:Provider/RawProvider、Snippet、Output/RawOutput(provider 具名输出),以及更新生命周期(UpdateState、Cache/Lifecycle/Parsabletrait,proxies_version版本化 +cached_json缓存)。thurgio-proxy— 25 种代理协议类型(SS、VMess、VLESS、Trojan、Hysteria(2)、TUIC、AnyTLS、ShadowTLS、Juicity、Naive、Ssh、Mieru 等),支持解析(ConfType:clash/meta/v2rayn/sip002/surge/qx/loon/singbox/sip008/ssd/telegram)和序列化;ProxyFormat<F>trait(markerV2rayN/Sip002/Surge/Qx/Loon)提供格式解析分发,formats.rs能力表为单一事实源。全部协议无条件编译。thurgio-formats— 共享行解析辅助(Surge/QX/Loon 行解析抽离,供 proxy 与 renderer 复用)。thurgio-proxy-singbox— Sing-box 特定的代理类型转换(CoreSingBox、ToSingBoxtrait,SProxyTy::supports单一能力源)。thurgio-filter— 代理过滤(Filter/RawFilter/Mode)、重命名(Rename)、emoji 模式(EmojiMap,aho-corasick)与规则集(RuleSet/RuleFormat,assets/rulesets/*.list内置表)。thurgio-script— 内联 JS 引擎(ScriptEngine::transform,boa_engine,js过滤器薄包装)。thurgio-renderer-api— 轻量级 API 合约:RenderTarget/Rendertrait +context::base_context/insert单一装配入口。零 Tera 依赖。thurgio-renderer— Tera 模板渲染:30+ 内置过滤器(general+proxy/qx/qx_config/loon/loon_config/mellow/mixed/stash/surfboard/clashr/singbox+rules/ruleset/sort_nodes/groups/js)+get_env/now;渲染线程池(Competing Consumers,EMA 平滑 backlog + 滞回控制 + FreeList,min=1 / max=64)。tpl=auto在 serverua.rs完成。thurgio-config— 配置加载、校验(模板存在性、来源 URL 格式、Setting::validate)与热重载(notify文件监听 +ArcSwap<T>无锁切换)。拆分读取provider.yaml/params.yaml/rename.yaml/filter.yaml/snippet.yaml/ruleset.yaml(后者支持http(s)://远程 URL 条目,更新管线物化)。thurgio-config-api— 轻量纯配置类型(Setting、Ttl、TokenScope、Tokens、EmojiMode、AdhocTplSetting),零领域/代理/过滤依赖。
数据访问层
thurgio-db— 基于 SQLite(sqlx,WAL 模式)的嵌入式持久化:KvStore(键值存储)、EntityStore/SqliteEntityStore(类型化实体存储)、Stored(领域对象 ↔ 存储模型关联)。
应用层
thurgio-app-state— 中央应用状态AppState:持有 SQLite 数据库连接、HTTP 客户端、渲染器、事件总线、熔断器池、构建/更新双锁(build_lock+update_lock,ADR-055)、data_generation(缓存降级用)、AdhocStore(临时资源内存+DB 缓存)与 dev/idle/evict 标志;render_context(build_render_context/build_base_context,ADR-057)为渲染装配单一入口。AppConfig为Ar<Config>新类型包装。thurgio-app— 外观(facade,分组 re-export:update/render/adhoc/config/admin,ADR-046):initialize三步初始化(Source → AppState → 熔断器恢复 → 事件处理器注册)。接口层 crate 仅经分组路径访问下层。thurgio-app-update— 更新管道编排(refresh_and_record统一入口,ADR-013;UpdateItemsStage<T: Stored>无界 fan-out,ADR-073;ensure_ready/refresh_in_background/refresh_and_wait_for分流,ADR-049/072;record私有ItemKind分发,ADR-032)。thurgio-app-build— 构建管道编排(build:update+record → 渲染 → 原子发布StagingDir,ADR-047)、渲染管道(RenderItemsStage,provider 主+具名输出平铺)、事件处理器(AutoBuildHandler/LoggingHandler/WebhookHandler/TelegramHandler)、模板目录监听(init_template_watcher)、并发任务工具(task::run_concurrent/try_join)。
接口层
thurgio-cli— CLI 二进制入口点(build/serve/init/check/diff nodes|file/config backup/restore/list/upgrade/generate/version,spawn_config_watcher统一监听thurgio.yaml+ 6 siblings +tpls/)。依赖thurgio-app外观 +thurgio-proxy::diff(节点级 diff)。thurgio-server— 基于 Axum 的 HTTP 服务器(build_router导出,12 read + 10 admin 端点,tpl=autoUA 自适应,SSE 事件流,限流/CORS/指标/认证中间件,静态资源include_str!嵌入)。
统一错误类型
ThurgioError(位于 thurgio-types)使用 thiserror 派生枚举,配套 ErrorKind 分类(Copy,用于状态码映射与重试决策):
ErrorKind | 含义 | HTTP | 可重试 |
|---|---|---|---|
Network | 网络请求失败(reqwest::Error) | 502 | ✅ |
Timeout | 请求超时 | 502 | ✅ |
Persistence | 数据库错误 | 500 | ❌ |
Parse | 数据解析失败 | 422 | ❌ |
Config | 配置错误 | 422 | ❌ |
Render | 模板渲染失败 | 500 | ❌ |
NotFound | 资源未找到 | 404 | ❌ |
Validation | 字段验证失败 | 422 | ❌ |
Unauthorized | 认证失败 | 401 | ❌ |
CircuitOpen | 熔断器打开 | 503 | ❌ |
Canceled | 操作取消 | 499 | ❌ |
Internal | 内部错误(anyhow::Error) | 500 | ❌ |
trace_id 通过外部包装 TracedError 携带,不嵌入 ThurgioError。详见 design/error-handling.md。
事件系统
事件总线实现解耦通信:
- 7 种事件:
RebuildRequested、ProviderUpdated、SnippetUpdated、BuildCompleted、RendererReloaded、ConfigReloaded(配置全量重解析并原子替换,ADR-048)、ServerEvent - 3 个默认订阅者:
AutoBuildHandler(RebuildRequested → 强制重建,仅重跑更新+渲染管线、不重载配置)、LoggingHandler(所有事件 → INFO/WARN)、WebhookHandler(BuildCompleted → 向THURGIO_WEBHOOK_URLPOST JSON,未设置时为空操作)
管道抽象
更新与渲染管道由阶段(stage)构成:
- 更新管道(
thurgio-app-update):UpdateItemsStage(providers)→UpdateItemsStage(snippets) - 渲染管道(
thurgio-app-build):providers(主输出 + 具名输出)与 snippets 两个阶段并发执行(共享不可变上下文,无共享可变状态)
特性门控
thurgio-proxy 不再按协议门控(25 种协议全部无条件编译),full/filters 拆分已移除(ADR-064),thurgio-domain 的 update/render-impl/db-impl 门控亦移除:
| 特性 | 说明 |
|---|---|
test-utils | 测试示例构造器(开发/测试用,仅 thurgio-proxy/thurgio-request 定义,thurgio-test-utils 消费 16 例) |
thurgio-cli 另有两个互斥的 TLS 后端特性:rustls-tls(默认)与 native-tls,通过 thurgio-app → thurgio-infra 转发到 reqwest。
依赖关系图
thurgio-cli ──> thurgio-app (facade)
├── thurgio-app-state ──> thurgio-config ──> thurgio-config-api
│ ├── thurgio-domain ──> thurgio-filter / thurgio-proxy / thurgio-proxy-singbox
│ ├── thurgio-renderer ──> thurgio-renderer-api
│ ├── thurgio-db / thurgio-request / thurgio-infra / thurgio-types
├── thurgio-app-update ──> thurgio-db / thurgio-infra / thurgio-request
├── thurgio-app-build ──> thurgio-renderer / thurgio-event
└── thurgio-event
thurgio-server ──> thurgio-app (facade)
关键 Trait
| Trait | Crate | 用途 |
|---|---|---|
Stored, EntityStore, SqliteEntityStore | thurgio-db | 存储模型关联 / 类型化实体存取 |
KvStore | thurgio-db | 键值持久化(SQLite) |
Proxy, ConfType, ProxyFormat | thurgio-proxy | 代理类型定义与格式解析分发(marker V2rayN/Sip002/Surge) |
CoreSingBox, ToSingBox | thurgio-proxy-singbox | Sing-box 转换 |
EventHandler, EventBus | thurgio-event | 事件订阅与分发 |
Render, RenderTarget | thurgio-renderer-api | 渲染数据合约(无 Tera 依赖) |
Renderable, Render, AppRenderEngine | thurgio-renderer | 模板渲染执行 |
设计原则
- 单一职责 — 每个 crate 有一个清晰的用途。
- 依赖反转 — 上层依赖于抽象。
- 关注点分离 — 各层干净分离。
- 外观模式 — 接口层 crate 通过
thurgio-app的重新导出访问下层。