Repository navigation
Releases: Walvez/dsh-search-failover
Release list
v0.3.23 — reset 零写入 + 写回不再有空字符串噪音
dsh-search-failover 0.3.23 — three real-host fixes on top of 0.3.22
0.3.22 made the search-pool settings page work again on DSH 0.2.1. Rolling it out on a real
profile surfaced three more defects, all fixed here.
Fixed
- "Restore inline config" wrote
apiKey: ""/apiKeyEnv: ""/baseURL: ""back into the
profile document for every backend that never had them (reproduced: 7 backends × 3 empty
fields). The save path was already cleaned; the reset path now goes through the same
cleanBackend(). - Clicking reset when nothing had changed still rewrote the entry, and DSH re-serialises the
node it edits — losing the hand-written comments and the compact- { id: … }style in the
profile document. Reset now compares the live values with the apply-time snapshot
(defaults filled, keys sorted, empty strings ignored) and performs zero writes when they
already match. The panel says "当前已是行内配置,未改写文档" in that case. cleanBackendlived inlib/routes.jsand was therefore invisible to the reset path; it now
lives inlib/settings-host.jsand is shared.
Verification (isolated instance, real web-profile document)
- Reset on an untouched document:
cordis.patch.ymlhash unchanged. - Switch strategy to rotate → save: strategy updated, 7 backends, 6
apiKeyEnvkept, zero empty
fields. - Reset afterwards: back to
failover, 7 backends, no empty fields,apiKeyEnvintact. npm test: 90/90.
🇨🇳 中文说明
0.3.22 让搜索池设置页在 DSH 0.2.1 上重新可用;在真实 profile 上跑起来后又暴露了三个问题,
本次一并修掉。
修复
- 「恢复行内配置」会把
apiKey: ""/apiKeyEnv: ""/baseURL: ""写回 profile 文档里
本来没有这些字段的后端(实测 7 个后端 × 3 个空字段)。保存路径原本已清洗,重置路径现在
也走同一个cleanBackend()。 - 什么都没改时点重置,仍会重写该 entry,而 DSH 会对被编辑的节点重新序列化 —— 手写注释和
紧凑的- { id: … }写法就此丢失。现在重置先和启动快照比对(补默认值、键排序、忽略空
字符串),相等时零写入,面板提示「当前已是行内配置,未改写文档」。 cleanBackend原来在lib/routes.js里,重置路径用不到;已移到lib/settings-host.js
共用。
验证(隔离实例,使用真实 web profile 文档)
- 未改动状态下重置:
cordis.patch.yml哈希不变。 - 策略改 rotate → 保存:strategy 更新、7 个后端、6 条
apiKeyEnv保留、零空字段。 - 再点重置:回到 failover、7 个后端、无空字段、
apiKeyEnv完整。 npm test:90/90。
v0.3.22 — DSH 0.2.1 settings-API compatibility / 适配 0.2.1 设置 API
dsh-search-failover 0.3.22 — DSH 0.2.1 settings-API compatibility (search pool settings page works again)
DSH 0.2.1-rc.2 removed the dsh-settings register() namespace API. Until now the search
pool settings page silently degraded: the host logged
[search-pool] settings register failed: sctx.settings.register is not a function and the
panel could not persist anything.
What changed
lib/settings-host.jsrewritten as a two-generation adapter:describe()/mutate()(0.2.1,
Config volatile fields + path ops) with the 0.2.0register()/scope path kept as fallback,
and a read-only inline-config mode when neither exists. The public shape stays
source()-callable, so existing call sites keep working.lib/index.jsnow exportsConfig = SearchPoolSettings(0.2.1 derives the settings page from
entry.fiber.runtime.Config), reads live values through the Config refs, and disables the
auto-generated generic form viasettings.configure({ auto: false })because the plugin ships
its own panel.lib/routes.jswrites through the new store (update()/reset()) and reads only
store.raw()— the entry's declared values, not the env-resolved ones.
Bugs found and fixed while porting
- "Reset to inline config" used
unset, which on 0.2.1 also deletes the inlinebackends
written by hand in the profile patch document (reproduced: 7 backends vanished). It now writes
the apply-time snapshot back explicitly, and refuses when no snapshot is available. describe()stripsrole('secret')fields to placeholders — key reading goes through Config
refs instead.- The write path read the merged live config, whose
apiKeyvalues are already resolved from
.env; one save would have written every plaintext key into the git-tracked profile document.
It now readsstore.raw()only. normalizeConfig()rebuilt backends from a fixed field list and droppedapiKeyEnv, so any
save made the.envkeys stop resolving on the next boot. Unknown fields are preserved.- Empty-string fields (
apiKey: "",apiKeyEnv: "") are no longer written back into the document.
Tests: 87/87 (node --test), including new test/settings-host.test.js and test/routes.test.js
plus the 0.3.16 abort-not-a-circuit-failure case.
Upgrade: dsh plugin --profile web add dsh-search-failover@0.3.22 (peer @deepseek-ai/schemastery
is now ^3.18.5, which ships .volatile()).
🇨🇳 中文说明
DSH 0.2.1-rc.2 删掉了 dsh-settings 的 register() 命名空间 API,搜索池设置页从那时起一直
静默降级:宿主只打印 [search-pool] settings register failed: sctx.settings.register is not a function,面板存不了任何东西。
改动
lib/settings-host.js重写为两代适配层:0.2.1 走describe()/mutate()(Config 的 volatile
字段 + 路径操作),0.2.0 的register()/scope 分支保留,两者都没有时降级为只读行内配置。
对外仍是可调用的source(),老调用点不用改。lib/index.js导出Config = SearchPoolSettings(0.2.1 靠entry.fiber.runtime.Config生成
设置页),通过 Config 引用读实时值;插件自带面板,所以用settings.configure({ auto: false })
关掉自动生成的通用表单。lib/routes.js写入走新 store(update()/reset()),读值只用store.raw()(入口声明值,
不是被 env 解析后的值)。
移植过程中发现并修掉的坑
- 「恢复行内配置」原用
unset,在 0.2.1 下会连 profile 补丁文档里手写的backends一起删掉
(实测 7 个后端消失)。现在改为把 apply 时的快照显式写回,取不到快照时直接报错。 describe()会把role('secret')字段剥成占位符 —— 读 key 改走 Config 引用。- 写路径原先读「合并后的生效配置」,那里的
apiKey已被.env解析成明文,保存一次就会把
所有明文 key 写进 git 跟踪的 profile 文档。现在只读store.raw()。 normalizeConfig()按固定字段重建 backend,把apiKeyEnv抹掉了 —— 保存一次,下次启动
.env里的 key 全部失效。现在保留未声明字段。- 写回文档时不再刷入
apiKey: ""/apiKeyEnv: ""这类空字符串。
测试 87/87(node --test),新增 test/settings-host.test.js、test/routes.test.js,并回补
0.3.16 的 abort 不计熔断用例。
升级:dsh plugin --profile web add dsh-search-failover@0.3.22(peer @deepseek-ai/schemastery
现在是 ^3.18.5,才有 .volatile())。