Files
Cyrene_v2/internal/services/backthink/sinks.go
T
AskaEth ed5005307a feat(backthink): 自排 C1-2 本体 + TriggerUnknown 修 fail-open(V1)
- selfwake.go:WakeNow + 待跑槽容量 1(先探槽合并不过闸、槽空才过闸、同锁)+ 闸 4 轮/小时
  ($DATA_DIR/config/backthink.json,零新 env 键)+ 审计四条 what + 启动日志两键 + 组合根接线
- G-A(主人已批):TriggerUnknown 作零值、既有两值编号后移(语义不动),未知触发走**最紧分支**
- 5 个变异自检(拆闸/≤0 未回落/过闸挪到探槽前=G1 失效形态/槽无界/零值挪走)
⚠️ 服务侧已就绪但**她仍调不到**(自排工具面属 C1-3)⇒ 不得写「C 已完成」
2026-10-06 20:25:04 +08:00

58 lines
2.1 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package backthink
// 生产组合根在 backthink.New *之后* 才构建 gateway hub 与 channel
// bridge(hub 需要 loop,bridge 需要 loop 与主人档案,
// 两者都在更晚时才组装),因此构造时拿不到 ActiveClient 与
// IMAdapter 槽。这些设置器在 gateway / bridge 存在后注入它们,
// 并重建推送器,同时保留已解出的
// 频率门,使之后的推送路由正确。
// SetActiveSink 接入生产用的活跃 Web/原生客户端槽(gateway
// hub)并重建推送器。请在 gateway 存在之后、Start 之前调用。
func (b *Backthink) SetActiveSink(active ActiveClient) {
b.mu.Lock()
defer b.mu.Unlock()
b.deps.Active = active
b.rebuildPusherLocked()
}
// SetIMSink 接入生产用的 IM 桥槽(channel bridge)并重建
// 推送器。请在 channel bridge 存在之后、Start 之前调用。
func (b *Backthink) SetIMSink(im IMAdapter) {
b.mu.Lock()
defer b.mu.Unlock()
b.deps.IM = im
b.rebuildPusherLocked()
}
// SetAuditSink 接入审计出口(网关,design/12 §N C.5)。它与上面两个 setter 同属
// **晚绑定**:网关比 backthink 晚组装,构造时拿不到。它不重建推送器——审计不在推送
// 路径上,换一个出口(或注入 nil)都不影响投递。
func (b *Backthink) SetAuditSink(a Auditor) {
b.mu.Lock()
defer b.mu.Unlock()
b.deps.Audit = a
}
// currentAuditor 在生命周期锁下返回当前审计出口,因此在途的一轮自排拿到的是
// 一致快照,而不是「一半旧一半新」的两个出口。
func (b *Backthink) currentAuditor() Auditor {
b.mu.Lock()
defer b.mu.Unlock()
return b.deps.Audit
}
// rebuildPusherLocked 用当前槽位、频率门与推送出口替换
// 推送器。调用方必须持有 b.mu。
func (b *Backthink) rebuildPusherLocked() {
b.pusher = newPusher(b.deps.Active, b.deps.IM, b.gate, b.log).withExporter(b.deps.Exporter)
}
// currentPusher 在生命周期锁下返回当前推送器,因此一次槽位
// 换入绝不会与即将推送的并发思考轮发生竞态。
func (b *Backthink) currentPusher() Pusher {
b.mu.Lock()
defer b.mu.Unlock()
return b.pusher
}