
CLIProxyAPI v8.0.51 保存配置采用 O_TRUNC 就地截断写,写完之前文件是 0 字节,而 watcher 与远端镜像正好在这段空窗里各读一次;同一夜三张修复写入路径的补丁被推进,附今晚可做的四步处置。
7cad1cb71。internal/api/handlers/management/config_basic.go 第 101 行的 WriteConfig。第 114 行打开文件时带了 O_WRONLY|O_CREATE|O_TRUNC,权限 0644,写完再 Sync 落盘2。O_TRUNC 的语义是打开即清空。从 OpenFile 返回到 Write 完成之间,磁盘上那份 config.yaml 是 0 字节。
WriteConfig 全文,第 114 行的三个打开标志是本节的依据。图取自 v8.0.51 发行标签2internal/watcher/config_reload.go 第 59 行先 os.ReadFile 一次算内容哈希;第 84 行触发重载,第 99 行调 loadConfigFileFunc 再读一次3。len(data)==0 直接返回,日志写 ignoring empty config file write event。这道判断落在第一次读,重载那次读没有对应检查。
internal/store/objectstore.go 第 27 行有个常量 objectStoreConfigKey = "config/config.yaml",仓库里同一层还有 git 与 postgres 两份实现5。1631875b(#6631)修掉」,剩下六条它自己扛6。mergeable 为 clean;页面上只有 chatgpt-codex-connector[bot] 的自动评审,没有维护者写过一句。| 补丁 | 改什么 | 规模 | 状态 |
|---|---|---|---|
| #6603 | watcher、凭证、存储三处的写入竞态 | 21 文件 +2112/−70,32 提交 | open,clean,无维护者评审 |
| #6605 | 凭证文件改成原子写 | 23 文件 +1495/−80,16 提交 | open,clean,无维护者评审 |
| #6413 | 冷关闭时 429 的重置时刻可被覆盖 | 9 文件 +641/−1,7 提交 | open,clean,无维护者评审 |
config.yaml 不是唯一被原地覆盖的文件。sdk/auth/filestore.go 第 139 行先读旧内容,jsonEqual 判定相同就 break;不同则 os.OpenFile(path, os.O_WRONLY|os.O_TRUNC, 0o600) 再写7。O_TRUNC 的语义没变:打开即清空。凭证文件比配置文件更小,空窗更短,形状一样。internal/watcher/synthesizer/file.go 第 64 行遇 !json.Valid(data) 就 RecordIncompleteFile 并跳过;第 88 行对 len(data)==0 直接返回空8。TestWriteFileTempIsOwnerOnlyWhileHoldingNewContent 在改前是失败的,因为那一刻临时文件是 -rw-r--r--,里面已经是新 token9。*.json 是什么权限,0644 的一个个改成 600。sdk/cliproxy/auth/conductor_cooldown.go 第 1119 行是 case 429:,第 1129 行用 if !disableCooling { 把整段冷却计算包住。开关为真时,这一支不写任何恢复时刻10。disableCooling 为真、且 NextRetryAfter 与 Quota.NextRecoverAt 都为零时,把 Unavailable 与 Quota.Exceeded 一起清掉。conductor_selection.go 第 1163–1181 行的 requestRetryRoundExclusions 用 effectiveRequestRetryLimit 判,request-retry: 3 时同一张凭证能进 1 到 3 轮11。
case 429: 与第 1129 行的 if !disableCooling { 是这段的全部依据;关掉冷却之后,这一支连恢复时刻都不写10routing.cooldown.disable-cooling: true 加 request-retry: 3,被 429 的凭证立刻重发 4 次;经一个自身对 429 退避的上游代理,约 4 × 61 秒,一次失败请求要烧掉 4 分钟左右12。ExecutionSeq 水位;乱序回来的老调用只能把冷却时间往长里延。coolingDisabledRetry 零命中。routing.cooldown.disable-cooling,config.example.yaml 第 227 行的默认值是 false13。单个凭证也能覆盖它,别忘了翻 auth 文件。request-retry 默认 3(第 211 行),把它改到 1 或 0,一次请求对上游的发送次数立刻从 4 降到 2 或 1。curl 一次管理接口把配置读回来,确认为非空;同时看一眼远端镜像最近一次提交是什么内容。chmod 600 覆盖 auth 目录下的每个 *.json,等 #6605 合并后再交给代码。github.com
github.com
github.com
github.com
github.com
github.com
github.com
github.com
github.com
github.com
github.com
github.com
github.com
This story was produced automatically by a channel. One sentence is all it takes for Neodrop to keep producing for you.