feat(channels): IM 车道生成并写入真实 turn_id(user/assistant 成对 + 同源 WithTurnID;群聊隔离与静默语义不变)
This commit is contained in:
1 parent
ba1974038a
commit
8f6a75b7d7
9 files changed
+215
-21
No files matched your search
@@ -0,0 +1,31 @@
|
||||
package channelbridge
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"encoding/hex"
|
||||
"time"
|
||||
)
|
||||
|
||||
// 本文件承载 IM 车道自己的**回合标识**生成点(design/15 §2.5.9)。
|
||||
//
|
||||
// IM 与 Web 是两条独立的驱动路径:Web 由 gateway 编排器起路、由它生成权威 turnId
|
||||
// (gateway/ws_hub_turn.go 的 newTurnID),而 IM 由渠道桥自己驱动 loop
|
||||
// (inbound.go 的 runInboundTurn → b.run.Run)—— 桥接器就是**这条车道的回合权威**,
|
||||
// 因此这里生成的是真实归属:一条入站消息 → 一次 run → 一条回复,标识只在这一段
|
||||
// 生命周期内有效。绝不拿时间戳或会话 id 冒充 turn id —— 那是伪造归属,比留空更坏
|
||||
// (留空诚实地表示「不属于任何已知回合」,冒充则会让两个不同回合被分进同一桶)。
|
||||
//
|
||||
// 格式与 gateway 那份**逐字一致**(`turn-` + 16 位十六进制),使两条车道产出的
|
||||
// turnId 对任何消费方(前端按 (sessionId, turnId) 两级分桶)都是同一种东西。它成为
|
||||
// 第二处副本,是因为 gateway 那份未导出、且该包已冻结,无法共享 —— 不是有意另造。
|
||||
|
||||
// newTurnID 返回一个新的随机十六进制回合标识,用于把一次 IM 入站回合的落库行
|
||||
// (用户消息 + 助手回复)关联到同一路。它消耗 crypto/rand 源,源不可用时回退到
|
||||
// 纳秒时间戳,因此总能产出 id —— 空的 turnId 会静默破坏客户端的两级分桶。
|
||||
func newTurnID() string {
|
||||
var b [8]byte
|
||||
if _, err := rand.Read(b[:]); err == nil {
|
||||
return "turn-" + hex.EncodeToString(b[:])
|
||||
}
|
||||
return "turn-" + time.Now().UTC().Format("20060102150405.000000000")
|
||||
}
|
||||
Reference in new issue
Block a user