Repository navigation
v0.9.28
AutoBuddy v0.9.28
补上 v0.9.27 遗留的两处缺口:队列撑不住时不再静默丢弃、明细改为按时间保留。
背景
v0.9.27 参照 sub2api / CLIProxyAPI 重构了统计存储。sub2api 的完整调研
报告随后送达,回看发现有两处没做到位,本版补齐。
1. 队列撑不住时不再静默丢弃
sub2api 的原则写得很硬 —— submitMandatoryUsageRecordTask 永不静默丢弃:
它的有界 worker 池(128 worker / 16384 队列)在队列满时提交方内联执行,
关停窗口的丢弃也会降级同步,保证计费一条不丢。
我 v0.9.27 的兜底却写着:
if len(_PENDING) < _PENDING_MAX_BACKLOG:
_PENDING[:0] = batch
else:
print(f"... dropping {len(batch)}") # ← 悄悄扔掉这正是「悄悄少数据」,与 sub2api 的做法背道而驰。
现在改成:队列真的撑不住时,把这一批折算进聚合(fold_into_rollup)
再丢弃明细。
| 明细 | 汇总数字 | |
|---|---|---|
| 旧行为 | 丢失 | 随之丢失 |
| 新行为 | 丢失 | 完整保住(token 总数、调用次数、按天/模型/账号分布) |
统计页的数字仍然正确,只是查不到单次调用的详情。
「悄悄少数据」和「降级保汇总」是两件事,后者才是可接受的兜底。
2. 明细改为按时间保留
sub2api 明确提醒:
别用滑动窗口。你的「3000 条」本质是行数上限,改成时间维度保留
(usage_logs_days),历史跨度就不受数据量绑架。
v0.9.27 只把聚合行改成了按天保留,明细仍是 MAX_DETAIL = 3000 的
行数上限。而实测网关每天约 2000 条调用 —— 忙的时候只能看两天,
闲的时候能看一个月,能回溯多久是不确定的。
现在主维度改为时间:
- 新增
DETAIL_MAX_DAYS(默认 7 天,AB_TOKEN_DETAIL_DAYS可调) - 新增
_split_expired()按天裁剪,超期明细先折算进聚合再移除 MAX_DETAIL降级为文件体积护栏,只在时间维度不够用时兜底
一个易漏的细节:没有 date 字段的记录一律保留 ——
宁可多留,也不能把数据误判成过期删掉。
为什么明细是 7 天而不是 sub2api 的 90 天
sub2api 明细留 90 天,是因为它在 PostgreSQL 里有分区 + 按月 DROP,
存得起。本网关明细是单个 JSON 文件,每请求都要读写一次,
7 天 × 约 2000 条/天 ≈ 1.4 万条会让文件膨胀到数 MB,得不偿失。
所以这里做了取舍:明细 7 天(可查单次调用),聚合 90 天(可查长期趋势)。
趋势图本来就读聚合,长期回溯不受影响。
关于 sub2api 的第 5 条(上游数据刷新)
sub2api 建议:上游额度用惰性读 + 分级 TTL(成功 3min / 错误 1min
负缓存 / 探测 10min)+ singleflight + jitter,并把快照写回账号记录。
本项目的 officialUsage 由官方闭源引擎采集,实测无法触发重写 ——
该路径用不上这套机制,v0.9.27 已改为暴露陈旧度
(officialUsageFreshness 的 stale / ageDays / reason)如实告知。
我们自己能控的上游调用(如签到状态)本来就有 60s TTL,与此一致。
测试
_test_token_storage.py 从 16 项扩到 24 项:
[5] 明细按时间保留
超期明细被划为待折算
近期与今天的明细保留
无日期字段的记录一律保留
条数远未达上限时仍按时间裁剪(证明主维度是时间)
[6] 队列撑不住时不得静默丢弃
源码中不再出现 dropping 分支
降级为折算保汇总
折算后 token 总数被保住
全量 18 个测试文件 ✅ 全绿
五模块 AST ✅ 通过
升级说明
重建容器即可,/data 数据不受影响。
新增可选环境变量:
| 变量 | 默认 | 含义 |
|---|---|---|
AB_TOKEN_DETAIL_DAYS |
7 | 明细保留天数(0 = 不按时间裁剪) |
无数据库结构变更;现有明细与聚合文件会被就地沿用。
升级后首次落盘会把超过 7 天的明细折算进聚合 —— 这是预期行为,
长期趋势数据不会丢。