diff --git a/pkg/channels/wecom/dedupe.go b/pkg/channels/wecom/dedupe.go index 09f5a8a41..8ca98a30d 100644 --- a/pkg/channels/wecom/dedupe.go +++ b/pkg/channels/wecom/dedupe.go @@ -14,14 +14,18 @@ func markMessageProcessed(msgMu *sync.RWMutex, processedMsgs *map[string]bool, m msgMu.Lock() defer msgMu.Unlock() + if *processedMsgs == nil { + *processedMsgs = make(map[string]bool) + } + if (*processedMsgs)[msgID] { return false } (*processedMsgs)[msgID] = true - // Keep existing behavior: when over limit, reset dedupe map entirely. + // When over limit, reset dedupe map but keep the current message. if len(*processedMsgs) > maxEntries { - *processedMsgs = make(map[string]bool) + *processedMsgs = map[string]bool{msgID: true} } return true diff --git a/pkg/channels/wecom_dedupe_test.go b/pkg/channels/wecom_dedupe_test.go index 467f79979..71f987892 100644 --- a/pkg/channels/wecom_dedupe_test.go +++ b/pkg/channels/wecom_dedupe_test.go @@ -60,14 +60,19 @@ func TestMarkMessageProcessed_RotationClearsMapAtBoundary(t *testing.T) { t.Fatalf("expected map size 1 after first insert, got %d", len(processed)) } - // Inserting second unique message exceeds maxEntries and should reset map. + // Inserting second unique message exceeds maxEntries and should reset map, but keep the new message. if ok := markMessageProcessed(&mu, &processed, "msg-2", 1); !ok { t.Fatalf("second unique message should be accepted") } - if len(processed) != 0 { - t.Fatalf("expected map to be reset after rotation, got size %d", len(processed)) + if len(processed) != 1 { + t.Fatalf("expected map to retain current message after rotation, got size %d", len(processed)) } - if processed["msg-2"] { - t.Fatalf("expected current message marker to be cleared after rotation") + if !processed["msg-2"] { + t.Fatalf("expected current message marker to be retained after rotation") + } + + // Because msg-2 was retained, an immediate duplicate should be rejected. + if ok := markMessageProcessed(&mu, &processed, "msg-2", 1); ok { + t.Fatalf("duplicate message immediately after rotation should be rejected") } }