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) } } }