Skip to content

Releases: erikwang2013/e-cat

v7.1.1

Choose a tag to compare

@erikwang2013 erikwang2013 released this 18 Oct 16:08

Security

  • 升级 rustls 0.23.45 → 0.23.46,修复 RUSTSEC-2026-0346 / 0347 / 0348 / 0349
    (cargo audit --deny warnings 在 2026-10-14 新通告后失败)。
  • 升级 quinn-proto 0.11.16 → 0.11.18,修复 RUSTSEC-2026-0338 / 0339 / 0340 /
    0341 / 0342(含两条 high)。纯依赖升级,无 API 变更。

v7.1.0

Choose a tag to compare

@erikwang2013 erikwang2013 released this 18 Oct 16:01

Added

  • ecat-cli:ecat pet 子命令 —— list / show / export 浏览并导出项目宠物的
    13 个纯矢量形态(主形象 + 12 表情)。PetForm 枚举携带 slug、中英文名、README 短代码
    与内嵌 SVG;show 接受 slug、短代码、中文名或英文名(如 smile / :emoji-smile: / 笑)。
    资源随 ecat-cli 打包,ASSETS-LICENSE.md 一并分发(SVG 不是 Apache-2.0)。
  • 项目宠物纯矢量化 —— 主形象与 12 个表情全部改为纯矢量 SVG,不再内嵌位图;
    新增 scripts/generate_pet_assets.py 作为单一生成源,同步 docs/、12 份 i18n 与
    ecat-cli/assets/pet/,并以测试防止 CLI 内嵌资源与 docs/ 漂移。
  • Social Preview 更新 —— 使用新矢量形象重新生成 1280×640 卡片;crate 数与数据后端数
    改为从 workspace members 推导,不再硬编码。

Changed

  • 发布脚本 —— scripts/release.sh 支持 patch / minor / major / 显式 X.Y.Z,
    并在发布时同步全部 Cargo.toml(含 workspace 依赖与成员)、14 份 README、配置示例中的
    版本串;新增 main 分支、干净工作树、CHANGELOG 段落与 tag 冲突前置检查。
  • 文档 —— README 宠物章节补充 ecat pet 用法;ecat-cli/README.md 增加 Pet forms
    说明与授权提示。

Fixed

  • scripts/mk-social-preview.py 的圆形蒙版未乘 SVG 自身 alpha,导致 transparent 背景
    被渲染成黑色。

v7.0.0

Choose a tag to compare

@erikwang2013 erikwang2013 released this 08 Oct 17:34
v7.0.0 — 批次 5b:11 个数据后端的出站韧性(超时/熔断/并发上限)+ 13 个 crate 的 metrics 构造即注册

破坏性变更:11 个后端 Config 新增公开字段(query_timeout_secs / breaker / max_concurrency 或
max_pool_size / min_pool_size)。这些结构体无 Default 也无 non_exhaustive,用结构体字面量
构造的用户代码需要补字段(E0063);走 serde 配置的写法不受影响。

发布判据(Task 13 Step 5 全量闸门,七步全绿):
  cargo test --workspace            rc=0  1228 passed / 0 failed
  cargo test --workspace --doc      rc=0     4 passed / 0 failed
  cargo fmt --all -- --check        rc=0
  cargo clippy --workspace --all-targets -D warnings   rc=0
  4 crate --all-features            rc=0   181 passed / 0 failed
  13 crate --features metrics       rc=0  (16/13/17/22/21/21/22/23/20/28/17/20/35)
  无源文件 >=500 行 + 版本一致性 6 项全中

v6.0.0

Choose a tag to compare

@erikwang2013 erikwang2013 released this 08 Oct 05:32

⚠️ 破坏性变更

  • ecat-data:run_with_timeout 签名变更 —— (Option<Duration>, F) →
    (BackendKind, Option<Duration>, F),返回的错误类型由写死的 RdbmsError 改为泛型
    E: TimeoutError。全仓 13 个既有调用点已迁移。
  • ecat-data:删除公开静态量 QUERY_TIMEOUTS —— 由 TIMEOUTS(按 BackendKind
    分 7 维)+ timeout_counter(kind) 取代。它只覆盖 RDBMS,且在新维度下不再被递增 ——
    留着就是一颗哑弹:仍是公开 API,读它的人永远拿到冻结值。
  • (次要)RedisConfig / ClickhouseConfig 新增公开字段。两个结构体都没有 Default
    也没有 #[non_exhaustive],用结构体字面量构造的用户代码需要补字段;走 serde 配置的
    写法不受影响(新字段全部带 #[serde(default)],省略即默认)。

Added

  • ecat-data:泛型超时助手(原 run_with_timeout 只服务 RDBMS 一条路径):
    • BackendKind —— 7 个后端类别(Rdbms / Cache / Search / Graph /
      Document / Storage / Tsdb),判别值即 TIMEOUTS 下标,顺序不可改;
      BackendKind::slug() 给出 Error::reason 用的短标识。
      维度跟 trait 家族走而不是产品品类:ClickHouse 同时实现 SqlExecutor 与
      TsdbClient,按「调用点包着哪个 trait」分。
    • TimeoutError trait + 两个实现:RdbmsError(→ RdbmsError::Timeout)与
      ecat_errors::Error(→ ErrorCode::DeadlineExceeded,reason 填组件标识)——
      六个非 RDBMS trait 共用后者,不需要六套。
    • TIMEOUTS: [AtomicU64; 7] + timeout_counter(kind)。取槽走无 _ 分支的 match:
      将来加第 8 个维度时编译失败,而不是运行期数错槽。
    • 泛型 run_with_timeout(kind, timeout, fut):None = 禁用超时;
      Some(Duration::ZERO) = 立刻超时(不是禁用,别照抄本仓别处「0 = 禁用」的惯例)。
  • ecat-data:熔断器错误的映射公开 —— map_breaker_error 由 pub(crate) 改为 pub,
    并新增 breaker_error_to_backend_error(ecat_errors::Error 侧的同一套语义)。
    Redis / ClickHouse 的包装层与 RdbmsRouting 复用同一套:后端自身的错误原样透出,
    熔断打开/探测耗尽时后端根本没被调用,报「连接不可用」。
    分两个函数是因为 RdbmsError、ecat_errors::Error 与 BreakerError 都是外部类型,
    写不出统一的 From(孤儿规则)。
  • ecat-circuit-breaker:
    • Breaker::opened_total() —— Closed → Open 的累计次数(半开探测失败重新打开也计入),
      供 ecat_outbound_breaker_open_total。用 state() 轮询猜测「开了几次」是错的
      (轮询间隔决定准确性,两次探测之间开又关抓不到)。
    • BreakerState::code() —— 指标数值编码 0 = closed / 1 = open / 2 = half-open。
      放在枚举定义处而非指标侧,编码器与枚举才不会各改各的。
    • BreakerConfig 可反序列化:各字段 #[serde(default)],配置文件里 breaker: {}
      与 breaker: {"failure_ratio": 0.5} 都能解析。
  • ecat-metrics:三个出站指标的全进程唯一 collector ——
    register_outbound_metrics(backend, timeouts, breaker_opened, breaker_state)。
    ecat_outbound_timeouts_total / ecat_outbound_breaker_open_total /
    ecat_outbound_breaker_state,维度 backend。幂等:同一个 backend 重复注册覆盖
    (避免同一标签出现两份样本被抓取端判为重复)。collector 必须在 ecat-metrics 只建一份 ——
    registry() 是全进程一个,每 crate 各建一份会在 Registry 里撞名(见 Fixed 第二条)。
  • ecat-metrics:四个 ecat_rdbms_* 家族的唯一 collector ——
    register_rdbms_metrics(backend, connections, pool_timeouts, query_timeouts, transactions_leaked);ecat-data-sqlx / ecat-data-mssql 的 register_pool_metrics
    改为往里挂数据源(签名未变)。
  • ecat-data-redis:Cache 路径内置超时 + 熔断(用户代码零改动):
    • RedisConfig 新增 query_timeout_secs(0 = 禁用;未配置 = 30 秒)与 breaker
      (省略即保守默认:失败率 0.5 / 窗口 30 秒 / 打开 10 秒)。
    • RedisCache::breaker() 暴露熔断器句柄;超时计数按 BackendKind::Cache 维度。
    • opt-in feature metrics:register_outbound_metrics(Arc<Breaker>),标签 backend="redis"。
  • ecat-data-clickhouse:SqlExecutor 与 TsdbClient 两条路径内置超时 + 熔断 + 并发上限:
    • ClickhouseConfig 新增 query_timeout_secs / breaker / max_concurrency
      (未配置 = 32)。并发上限由本 crate 的信号量实现 —— reqwest 只有
      pool_max_idle_per_host(空闲保留数),没有「最大总连接数」,默认无背压。
    • 两条路径共用一个 Breaker(同一个服务器、同一个故障域);超时维度分别按
      Rdbms 与 Tsdb 计。
    • TsdbClient 实现搬到 src/tsdb.rs;_with 方法保持不进熔断器(见 Fixed 第三条)。
    • opt-in feature metrics:标签 backend="clickhouse" / backend="clickhouse-tsdb"。
  • docs/superpowers/checklists/backend-resilience-onboarding.md —— 5b 逐 crate 照做的
    出站韧性接入 checklist(8 节)。
  • docs/database-config-tutorial.md ×13 补 Redis / ClickHouse 的超时与熔断字段,
    并写明 Redis 多路复用的能力边界。

Fixed

  • ecat-circuit-breaker:半开探测名额泄漏(5.0.0 已发布缺陷)。
    Breaker::call 在半开分支于 f().await 之前借出探测名额,而名额的归还只在
    await 之后的记录逻辑里。于是 future 被外部取消(tokio::select!、调用方自己的
    超时层、请求处理被 drop)时名额有借无还 —— half_open_probes(默认 3)次之后
    half_open_count >= half_open_probes 恒成立,每次调用立即返回 ProbesExhausted,
    状态永久停在 HalfOpen
    ,只能靠重启进程恢复。
    修法:探测名额改为 RAII 的 ProbePermit,Drop 时归还;探测已记入窗口则 disarm
    不再归还。归还用 saturating_sub 是承重的(探测 A 挂起 → 探测 B 失败重开 → 冷却期
    Open → HalfOpen 清零计数 → A 这时被取消,减在 0 上是可达的)。
  • ecat-data-sqlx / ecat-data-mssql:四个 ecat_rdbms_* 同名家族互相顶掉
    (5.0.0 已发布缺陷)。
    两个 crate 的 register_pool_metrics 各建一份同名 collector,
    而 ecat-metrics 的 registry() 是全进程一个:prometheus::Registry 按名字去重,
    后注册者整份被 AlreadyReg 吞掉 ⇒ 它的四个指标一条样本都不输出,无报错、无日志,
    且单 crate 测试全绿(看不到另一个 crate 的注册)。
    修法:collector 唯一化到 ecat-metrics::register_rdbms_metrics,两个后端只挂数据源。
    指标名、HELP 文本与标签语义一字未改;新增跨 crate 回归测试
    (ecat-metrics/tests/rdbms_shared_families.rs,两个后端同进程时两族样本都在)。
  • ecat-data-clickhouse:transaction()(硬编码「ClickHouse 不支持事务」)与 _with
    方法(落到 SqlExecutor 的 trait 默认实现)不进熔断器 —— 两者都不含任何 I/O,
    包进去只会让「本就不支持的调用」被记成后端失败。加了两条把守测试防回归。

Known limitations

  • 熔断没有总开关:BreakerConfig 只有阈值字段,没有 enabled。要停用只能把阈值
    调到不可能触发(如 failure_ratio: 1.1)。配置教程已写明,别写 {"enabled": false}
    (那是反序列化错误)。

  • ecat-data-redis 仍走 MultiplexedConnection(多路复用),本版不换连接池 ——
    超时 + 熔断下多路复用的边界见配置教程。

  • RedisLock 的 DistributedLock 路径不在本版范围(用 LockError,不共用本套映射)。

  • 两个后端仍声明未使用的 prometheus 直接依赖:ecat-data-sqlx 与 ecat-data-mssql 的
    Cargo.toml 仍有 prometheus = { version = "0.13", optional = true },metrics feature 也仍写着
    ["dep:ecat-metrics", "dep:prometheus"] —— 但自本版起四个 ecat_rdbms_* 家族的 collector 搬到了
    ecat-metrics,这两个 crate 已零 prometheus 引用。本版不删:feature 列表是对外可见的,
    删它超出「换注册方式」的范围,留作后续清理。

  • README 的后端能力表未更新(本版只改了版本号):表里 ClickHouse / QuestDB 两行的
    ✅ 熔断 仍指「可被 CircuitBreakerExecutor 包装」,而 ClickHouse 本版起已是内置;
    配置字段表(ClickhouseConfig 的 base_url 等)也还没列出三个新字段。
    整体留给下一批与其余 10 个后端一并同步 —— 14 份手写镜像同步一次就够,不做两遍。

v5.0.0

Choose a tag to compare

@erikwang2013 erikwang2013 released this 08 Oct 05:32

⚠️ 破坏性变更

  • ecat-data:RdbmsError 新增 NoAvailableReplica 变体。
    副本全部熔断且 RdbmsRouting::fallback_to_primary(false) 时返回它。
    该 enum 不是 #[non_exhaustive],因此下游任何穷举 match 会编译失败 ——
    这是本版进位主版本号的唯一理由。
    (给它加 #[non_exhaustive] 降级不行:对已有的公开 enum 加该属性本身也是破坏性变更。)

Added

  • ecat-circuit-breaker 抽出公开的熔断状态机(批次 5「14 个后端出站韧性」的前置):
    • Breaker + BreakerConfig + BreakerState + BreakerError
    • Breaker::state() —— 供调用方读熔断状态;含冷却期的 Open → HalfOpen 转换
    • 原 tower 的 CircuitBreakerLayer / CircuitBreakerService 公开签名未变(内部改为委托 Breaker),
      12 个既有测试逐条保持全绿
    • 该 crate 从单文件 546 行拆为 4 个文件(原文件已超项目 500 行约定)
  • ecat-data:CircuitBreakerExecutor<S> —— 给任意 SqlExecutor 逐端点包一层熔断。
    熔断打开时内层一次都不被调用;dialect() 不经熔断(纯本地判断)。
  • ecat-data:RdbmsRouting —— 读写分离(写落主、读落从轮询、query_write 落主、
    事务落主且不经熔断),并跳过熔断打开的副本。
    只做逐端点包熔断是不够的:从库挂掉后轮询仍会把 1/N 的读转过去靠熔断快速失败 ——
    那不是故障隔离,是稳定的 1/N 失败率。fallback_to_primary 控制副本全不可用时降级还是报错。
  • ecat-data-sqlx / ecat-data-mssql:三个 opt-in feature(默认关闭,避免把 axum 拖进核心依赖树):
    • metrics —— register_pool_metrics(backend, pool),四个指标
      (ecat_rdbms_pool_connections / _pool_timeouts_total / _query_timeout_total /
      _transactions_leaked_total)。后两个接既有的进程级计数 QUERY_TIMEOUTS /
      TRANSACTIONS_LEAKED —— 把日志变成可告警的指标。
    • health —— RdbmsHealthCheck 实现 ecat_health::HealthCheck(池连通性 SELECT 1)。
    • tracing —— 超阈值 SQL 打 warn,阈值 slow_query_ms 可配;SQL 按字符截断
      (不切半个 UTF-8),上限 SQL_HEAD_CHARS = 200。
  • ecat(聚合入口):两个 opt-in feature orm / mssql,并补上对应重导出。

Fixed

  • ecat-circuit-breaker:state() 此前不做冷却期转换 —— 而 RdbmsRouting 靠它跳过
    Open 的端点,于是被跳过的端点永远没人调 call(转换在 call 里),
    冷却期过后也不会被重新放行。后果不是「暂时少一个副本」,是任何失败过的副本被永久排除,
    读能力单调缩水。现 state() 报告有效状态(冷却已过则报 HalfOpen)。

Docs

  • 修正多处文档与代码矛盾(均为既有问题,非本版引入):
    • TLS 教程里的 tls: {} # 保留字段 —— SqlxConfig.tls 实际是配了就报错
      (批次 1 改的「响亮失败而非静默忽略」),照抄该 yaml 会启动失败。
    • 「所有后端均支持 tls 字段」—— 两处反例:ecat-data-sqlx 配了报错、
      ecat-data-memcached 声明了但全 crate 无人读(静默无效)。
    • 生态规划里「三项破坏性变更尚未发布;3.0.3 → 4.0.0」—— v4.0.0 / v4.1.0 均已发布。
    • README 的 crate 数(51 → 56)、README.en.md 标题的后端数(18 → 19)、
      多数据源列表补 SQL Server、目录树删除两个不存在的目录。
    • docs/i18n/{id,en,es,fr,ja,pt,ru} 的目录树注释为中文残留 → 各语言译文
      (4.1.0 新增的行本就已翻译,旧 56 行是半截翻译)。
  • 新增 docs/social-preview.png(1280×640)。
  • 12 语言 README / 生态规划 / 数据库配置教程同步更新。

Known limitations

  • ecat-data-memcached 的 tls 字段是死字段:声明了但全 crate 无人读,配了静默无效。
    与批次 1 修掉的 SqlxConfig.tls 同族,但改它是行为变更,留作独立任务。
  • ecat-data-clickhouse(OLAP)未列入 README 的「多数据源」一行(表内有),既有遗漏。
  • RdbmsRouting 的内置 Endpoint 会在调用方已用 CircuitBreakerExecutor 包装端点时双重包装。

v4.1.0

Choose a tag to compare

@erikwang2013 erikwang2013 released this 08 Oct 05:32

Added

  • 新 crate ecat-orm + ecat-orm-derive(完整 ORM)。建立在 4.0.0 拆出的
    SqlExecutor 之上 —— 所有数据操作取 &impl SqlExecutor,因此客户端与 Transaction 通吃。
    • #[derive(Entity)]:表名/列/主键/标志位、from_row/to_values、关联与 XxxRelation 枚举、set_relation 写回口
    • 方言层 DialectSpec:SQLite / PostgreSQL / MySQL / SQL Server / ANSI 五套纯函数 SQL 生成
    • 查询构建器:类型状态 Unfiltered → Filtered(无过滤条件无法删改,编译期保证)+ 标识符白名单(未声明的列名不拼进 SQL)
    • CRUD(insert / find_by_id / find_all / update / delete_by_id / hard_delete_by_id / save)
    • 批量分块:按各方言参数上限(SQLite 999 / SQL Server 2100 / 其余 65535)切分
    • 分页(Page<T> / paginate / paginate_without_count)
    • 关联预加载:一次 IN 查询取回全部关联,杜绝 N+1(三种方向:has_many / has_one / belongs_to)
    • 自动行为:created_at / updated_at 填充、软删除、乐观锁(version 冲突报 OptimisticLockConflict)
    • 迁移系统:Migrator(add / status / run / down)+ 实体工厂 create_table::<E>() + 版本表 _ecat_migrations
  • ecat-data:SqlExecutor::execute_then_query(有默认实现,向后兼容)——
    在同一条连接上原子地跑两条语句。Transaction 覆写为「直接在自己身上跑」,
    SqlxClient 覆写为「开事务跑完提交」。这是「事务内 insert」能成立的前提
    (MySQL 的 LAST_INSERT_ID() 是连接作用域的)。

Changed

  • ecat-data:DialectSpec::table_exists_sql 改名 create_table_prefix 并改语义 ——
    旧名承诺「一条语句」,但在 SQL Server 上返回空串,调用方照名字用会生成没有
    CREATE TABLE 关键字的非法 SQL。新名始终返回完整前缀(MSSQL 为 CREATE TABLE [x]),
    另加 needs_exists_check_before_create() 表达「建表前需先查存在性」。
  • ecat-data:DialectSpec::limit_clause 的 limit 参数改 Option<u64> ——
    旧版用 u64::MAX 表示「未设置」,offset() 不带 limit() 时会生成
    LIMIT 18446744073709551615 OFFSET 20,超出 BIGINT、真库拒收。
  • ecat-data / ecat-data-sqlx:find_by_id / find_all 改走统一的查询构建器路径
    (列清单、方言引号、占位符编号、软删除闸门全在一处,不另写第二条 SQL 生成路径)。

Known limitations

  • sqlite::memory: 不支持跨连接事务场景:池只有一条被事务占住的连接,事务内第二条
    语句会等到超时。需要多连接时用文件路径(sqlite:<path>?mode=rwc)。
  • join 的列清单不带表前缀:被连表与主体有同名列时真库报 ambiguous column name。
  • 批量 update_many 的乐观锁冲突无法定位到行:只能靠「返回行数 < 传入行数」察觉,
    需要定位时用逐行 update。
  • join 的表名与 ON 条件不做白名单校验(join(table, on) 收的是字符串,
    字符串里没有类型信息);与 filter_raw 同一信任边界,文档已注明。

Tests

  • ecat-orm 的 SQLite 全链路集成测试:实体定义 → 迁移建表 → CRUD → 关联预加载 →
    分页 → 事务提交/回滚 → 软删除 → 乐观锁冲突,外加时间列无 CAST 往返
    (断言在绑定参数上 —— SQLite 读路径会重新格式化偏移量文本,读回路断言是空的)。
  • 发布前 cargo test --workspace:1076 passed / 0 failed(4.0.0 时为 771)。
    --doc 有 4 条 doctest 实际执行(2 条 compile_fail + 2 条正向对照)——
    编译期断言必须放在 src/ 的非 #[cfg(test)] 位置:写在 tests/*.rs 里
    rustdoc 不收,写在 #[cfg(test)] mod 里 --doc 编译时不开 cfg(test),两处都不会执行。

v4.0.0

Choose a tag to compare

@erikwang2013 erikwang2013 released this 08 Oct 05:32

⚠️ 破坏性变更

  • ecat-data:RdbmsClient 拆出 SqlExecutor supertrait。执行与方言能力
    (execute / query / execute_with / query_with / query_write / dialect)
    移入 SqlExecutor,RdbmsClient 只剩 transaction()。直接实现过 RdbmsClient
    的下游会编译失败。仓库内 4 个实现者(SqlxClient / ClickhouseClient /
    QuestdbClient / 测试桩)已同步适配。
  • ecat-data:TransactionInner 签名扩张,Transaction 现在实现 SqlExecutor
    —— 事务内可执行 SQL(此前只能 commit / rollback)。
    空事务(Transaction::new())执行 SQL 现在报错而非静默返回 0 行影响。
  • ecat-data-sqlx:from_pool(AnyPool, Dialect) → from_pool(Pool),
    并弃用 AnyPool,改用 PG / MySQL / SQLite 三路原生池。
  • ecat-data-sqlx:SqlxConfig.tls 设了就报错(此前被 serde 接受但代码从不读,
    是静默无效的配置项);TLS 请走 URL 参数(如 ?sslmode=require)。

Added

  • 新数据后端 ecat-data-mssql(SQL Server) —— 数据后端从 15 个增至 16 个。
    基于 tiberius-ng 0.13 + deadpool 0.13,实现完整 SqlExecutor +
    RdbmsClient。支持 URL 形态(mssql://user:pass@host:1433/db,含
    encrypt / trustservercertificate 查询参数)与 ADO 形态
    (Server=host,1433;Database=db;User Id=...)两种连接串。
  • ecat-data:Dialect 枚举与 Dialect::from_url(大小写与首尾空白/控制字符均容忍)。
  • ecat-data:查询超时助手 run_with_timeout,以及进程级超时计数
    QUERY_TIMEOUTS / 事务泄漏计数 TRANSACTIONS_LEAKED。
  • ecat-data-sqlx:连接池参数(max_connections / min_connections /
    acquire_timeout_secs / idle_timeout_secs / max_lifetime_secs /
    query_timeout_secs / test_before_acquire)与 session_init
    (会话初始化,默认按方言把库侧时区设为 UTC)、warm_up() 预热。
  • docker-compose.dev.yml:本地联调三库一键起(SQL Server 2022 / PostgreSQL 16 / MySQL 8.0),
    不进 CI。

Fixed

  • ecat-data-sqlx:类型映射的 5 个静默错值(均由真库 A/B 实测发现)——
    MySQL UNSIGNED 整数此前在 Bool/Null 之间跳(BIGINT UNSIGNED 正是最常见的自增主键)、
    PG smallint 返回 Null、bool 分支抢走整数、NULL 无闸门(sqlite 下 NULL 会静默变 false)、
    OffsetDateTime 的 Display 被误当作 RFC3339。未支持类型(numeric / uuid / jsonb 等)
    现在响亮报错(带列名与类型名)而非静默返回 null。
  • ecat-data-sqlx:DATE 输出纯 YYYY-MM-DD,不伪造源数据里不存在的时刻与时区。
  • ecat-data-sqlx:池默认值单一来源(pool() 与 PoolParams::default() 此前会静默分叉);
    connect() 与 from_config() 的方言默认会话初始化此前不一致。
  • ecat-data-mssql:idle_timeout_secs 是空配置(deadpool 不提供空闲回收),已删除;
    MssqlConfig 加了 deny_unknown_fields(拼错的键名此前被静默忽略)。
  • ecat-data / ecat-data-sqlx / ecat-data-mssql:事务方法补上查询超时
    (此前事务内挂死的查询会永久占住连接)。
  • ecat-mq-nats:显式安装 rustls crypto provider。此前依赖「ring 与 aws-lc-rs
    两个特性恰好启用一个」这一脆弱不变量 —— 任何引入第二个 provider 的依赖都会让它 panic
    (且只在 cargo test --workspace 的特性合并下暴露)。全仓其余 4 处早已显式安装,
    此处是唯一遗漏。
  • ecat-data-clickhouse:建表缓存的 TTL 测试去掉时间依赖(5ms 余量导致 ~0.67% 概率假失败)。

Security

  • 升级 h2 0.4.15 → 0.4.19(RUSTSEC-2026-0258)、rustls 0.23.43 → 0.23.45
    (RUSTSEC-2026-0285,5.3 medium)、chacha20 0.10.1 → 0.10.2(此前版本已 yanked),
    连带 rustls-webpki 0.103.13 → 0.103.15。cargo audit --deny warnings 闸门转绿。

Tests

  • ecat-data-sqlx / ecat-data-mssql:env 门控真库集成测试
    (ECAT_TEST_PG_URL / ECAT_TEST_MYSQL_URL / ECAT_TEST_MSSQL_URL;
    ECAT_REQUIRE_LIVE_DB=1 让 CI 里「跳过即失败」)。三者与 SQLite 一起覆盖四类后端。
  • 真库用例做过三向验证:真 URL 通过 / 死端口必须失败(证明真在连库)/ 未设 URL 且
    REQUIRE 时 panic 并点名缺失键。
  • 发布前 cargo test --workspace:771 passed / 0 failed / 0 panic(115 个测试二进制,
    67 个套件)。跨 crate 特性合并是必需的一层 —— 本版 ecat-mq-nats 的 rustls provider
    panic 只在这一层暴露,单 crate 跑 60 次全过。

v3.0.3

Choose a tag to compare

@erikwang2013 erikwang2013 released this 23 Sep 02:31

API 参考文档 docs/api.md:端口约定、/health /ready /metrics 内置端点、错误格式、GraphQL/OpenAPI/WebSocket/版本路由扩展接口
12 语言文档目录 docs/i18n/{en,ja,ko,ru,de,fr,es,pt,hi,ar,bn,id}/:全部 24 份文档翻译 + 3 张图片副本,README 顶部语言切换器互链

v3.0.2

Choose a tag to compare

@erikwang2013 erikwang2013 released this 26 Aug 17:24
v3.0.2: 审计修复全部落地 + 全面测试 + 文档水印 + 推送规则

修复(审计 8.17 backlog + 测试报告):
- workspace: tokio minimal features、rustls-tls-no-provider、删死 crate(ecat-tracing-otlp/ecat-testing)、日志/追踪合并、lto=thin
- auth: JWT key 一次构建、oauth2 1MiB+sub 必填、purge 阈值
- data: 6 单变体错误枚举统一 ecat-errors、8 crate 迁移、s3 默认 https、rdbms rollback 幂等
- security: MQ TLS/SASL 配置面(kafka/nats/mqtt/rabbitmq)、WS 大小可配、Consul 强制 https、client 不跟随重定向、413 语义、ratelimit proxy 头 opt-in
- graphql: 查询复杂度限制(默认 10_000)
- 测试报告修复: ecat-security URI 百分号解码防 SQLi 绕过、sqlx 驱动安装、influxdb 转义/排序、clickhouse 建表 TTL

测试:51 crate 全面单测 +206(675 全绿),报告 docs/test-report-2026-08-26.md
文档:README 版本/数量同步 3.0.2、CHANGELOG 3.0.2、图片加水印 erik.xyz
推送规则:scripts/release.sh(最新版本增量 bump → 提交推送 → tag,跳过打包)

v3.0.1

Choose a tag to compare

@erikwang2013 erikwang2013 released this 17 Aug 02:57
v3.0.1: 审计 5 项修复 + 版本同步 3.0.1(reviewer APPROVED)

- ecat-mq-kafka auto_commit=true 消息丢失量化告警(break 前 warn 未消费条数)
- ecat-data rdbms rollback 误报修复(rolled_back 标志)
- OAuth2 内省 1MiB 有界读取 + sub 缺失/空拒绝
- [profile.release] lto="thin"
- 补 FileSource::load() 4 测试 + circuit-breaker 状态机 2 测试
- 版本三处同步:Cargo.toml 16 处、Chart.yaml appVersion、CHANGELOG