Keine Beschreibung
Du kannst nicht mehr als 25 Themen auswählen Themen müssen mit entweder einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

cache.go 2.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. package event
  2. import (
  3. "sync"
  4. "time"
  5. )
  6. // SessionUserCache 会话-用户映射缓存,支持TTL过期
  7. type SessionUserCache struct {
  8. mu sync.RWMutex
  9. cache map[string]cacheEntry
  10. ttl time.Duration
  11. stopChan chan struct{}
  12. }
  13. // cacheEntry 缓存条目
  14. type cacheEntry struct {
  15. userID string
  16. expiresAt time.Time
  17. }
  18. // NewSessionUserCache 创建新的会话-用户缓存
  19. func NewSessionUserCache(ttl time.Duration) *SessionUserCache {
  20. cache := &SessionUserCache{
  21. cache: make(map[string]cacheEntry),
  22. ttl: ttl,
  23. stopChan: make(chan struct{}),
  24. }
  25. // 启动清理协程
  26. go cache.cleanupWorker()
  27. return cache
  28. }
  29. // Set 设置会话-用户映射
  30. func (c *SessionUserCache) Set(sessionID, userID string) {
  31. c.mu.Lock()
  32. defer c.mu.Unlock()
  33. c.cache[sessionID] = cacheEntry{
  34. userID: userID,
  35. expiresAt: time.Now().Add(c.ttl),
  36. }
  37. }
  38. // Get 获取用户ID,如果不存在或已过期返回空字符串
  39. func (c *SessionUserCache) Get(sessionID string) string {
  40. c.mu.RLock()
  41. entry, exists := c.cache[sessionID]
  42. c.mu.RUnlock()
  43. if !exists {
  44. return ""
  45. }
  46. // 检查是否过期
  47. if time.Now().After(entry.expiresAt) {
  48. // 异步删除过期条目
  49. go c.deleteIfExpired(sessionID)
  50. return ""
  51. }
  52. return entry.userID
  53. }
  54. // Delete 删除指定会话的缓存
  55. func (c *SessionUserCache) Delete(sessionID string) {
  56. c.mu.Lock()
  57. defer c.mu.Unlock()
  58. delete(c.cache, sessionID)
  59. }
  60. // deleteIfExpired 检查并删除过期条目
  61. func (c *SessionUserCache) deleteIfExpired(sessionID string) {
  62. c.mu.Lock()
  63. defer c.mu.Unlock()
  64. if entry, exists := c.cache[sessionID]; exists {
  65. if time.Now().After(entry.expiresAt) {
  66. delete(c.cache, sessionID)
  67. }
  68. }
  69. }
  70. // cleanupWorker 定期清理过期条目的工作协程
  71. func (c *SessionUserCache) cleanupWorker() {
  72. ticker := time.NewTicker(c.ttl / 2)
  73. defer ticker.Stop()
  74. for {
  75. select {
  76. case <-ticker.C:
  77. c.cleanupExpired()
  78. case <-c.stopChan:
  79. return
  80. }
  81. }
  82. }
  83. // cleanupExpired 清理所有过期条目
  84. func (c *SessionUserCache) cleanupExpired() {
  85. c.mu.Lock()
  86. defer c.mu.Unlock()
  87. now := time.Now()
  88. for sessionID, entry := range c.cache {
  89. if now.After(entry.expiresAt) {
  90. delete(c.cache, sessionID)
  91. }
  92. }
  93. }
  94. // Stop 停止缓存清理协程
  95. func (c *SessionUserCache) Stop() {
  96. close(c.stopChan)
  97. }