package backthink // eventRedundant 报告 tr 是否与前一次事件驱动的推送重复 // (同源 + 同摘要),因此重复的设备/提醒事件 // 不会刷屏主人(防刷)。当 PushGate 对事件本身被绕过时, // 它是仅剩的一道仍适用于事件驱动推送的 // 门(主人要求:"该发就发"——真正的事件照发,只扣下真正的重复)。 // // 推送进行时它原子地把 tr 记为最新事件键,并在任何非事件推送 // (非事件轮:心跳 / 启动轮 / 她自己排起的一轮)时清除该键,以免更早事件的再次 // 重复被中间一次反思错误地抑制。 // // 自排轮与心跳同分支(清链、不去重):它既不是外部事件、就不该参与事件链, // 因此真实事件的重复链不会被自排轮错误抑制;自排轮的推送仍由 PushGate 兜。 // // 未知触发(TriggerUnknown)也走这一支:它**不是**事件,故不去重;它同样不绕 // PushGate(push.go 只对 TriggerEvent 放行),因此重复投递的上限仍由频次门兜住。 // // 调用方把它跑在把推送交给 Pusher 之前;真正的重复 // 会被记为已抑制(RouteNone),而不是投递出去。 func (b *Backthink) eventRedundant(tr Trigger) bool { if tr.Kind != TriggerEvent { // 非事件轮(心跳 / 启动轮 / 自我唤醒轮)会打断同一事件链。 b.eventMu.Lock() b.lastEventKey = "" b.eventMu.Unlock() return false } key := tr.Source + "\x00" + tr.Summary b.eventMu.Lock() defer b.eventMu.Unlock() if b.lastEventKey == key { return true } b.lastEventKey = key return false }