Files
Memoh/internal/channel/adapters/wecom/callback_cache.go
T
BBQ bc47655309 fix(wecom): align adapter with channel stream behavior
Migrate the imported WeCom adapter to current channel interfaces and stabilize stream delivery by preventing heartbeat/reply ACK timeout regressions and post-final overwrite updates.
2026-03-11 02:14:00 +08:00

78 lines
1.4 KiB
Go

package wecom
import (
"strings"
"sync"
"time"
)
type callbackContext struct {
ReqID string
ResponseURL string
ChatID string
UserID string
CreatedAt time.Time
}
type callbackContextCache struct {
mu sync.RWMutex
items map[string]callbackContext
ttl time.Duration
}
func newCallbackContextCache(ttl time.Duration) *callbackContextCache {
if ttl <= 0 {
ttl = 24 * time.Hour
}
return &callbackContextCache{
items: make(map[string]callbackContext),
ttl: ttl,
}
}
func (c *callbackContextCache) Put(messageID string, ctx callbackContext) {
key := strings.TrimSpace(messageID)
if key == "" {
return
}
if ctx.CreatedAt.IsZero() {
ctx.CreatedAt = time.Now().UTC()
}
c.mu.Lock()
c.items[key] = ctx
c.gcLocked()
c.mu.Unlock()
}
func (c *callbackContextCache) Get(messageID string) (callbackContext, bool) {
key := strings.TrimSpace(messageID)
if key == "" {
return callbackContext{}, false
}
c.mu.RLock()
item, ok := c.items[key]
c.mu.RUnlock()
if !ok {
return callbackContext{}, false
}
if time.Since(item.CreatedAt) > c.ttl {
c.mu.Lock()
delete(c.items, key)
c.mu.Unlock()
return callbackContext{}, false
}
return item, true
}
func (c *callbackContextCache) gcLocked() {
if len(c.items) < 512 {
return
}
now := time.Now().UTC()
for key, item := range c.items {
if now.Sub(item.CreatedAt) > c.ttl {
delete(c.items, key)
}
}
}