53 lines
1.1 KiB
Go
53 lines
1.1 KiB
Go
|
|
package cache
|
|||
|
|
|
|||
|
|
import (
|
|||
|
|
"strings"
|
|||
|
|
"sync"
|
|||
|
|
"time"
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
// memoryFallback Redis 不可用时的内存备用缓存,保证服务可用
|
|||
|
|
var (
|
|||
|
|
memoryMu sync.RWMutex
|
|||
|
|
memoryData = make(map[string]*memoryEntry)
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
type memoryEntry struct {
|
|||
|
|
Data []byte
|
|||
|
|
Expiry time.Time
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
func memoryGet(key string) ([]byte, bool) {
|
|||
|
|
memoryMu.RLock()
|
|||
|
|
defer memoryMu.RUnlock()
|
|||
|
|
e, ok := memoryData[key]
|
|||
|
|
if !ok || e == nil || time.Now().After(e.Expiry) {
|
|||
|
|
return nil, false
|
|||
|
|
}
|
|||
|
|
return e.Data, true
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
func memorySet(key string, data []byte, ttl time.Duration) {
|
|||
|
|
memoryMu.Lock()
|
|||
|
|
defer memoryMu.Unlock()
|
|||
|
|
memoryData[key] = &memoryEntry{Data: data, Expiry: time.Now().Add(ttl)}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
func memoryDel(key string) {
|
|||
|
|
memoryMu.Lock()
|
|||
|
|
defer memoryMu.Unlock()
|
|||
|
|
delete(memoryData, key)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// memoryDelPattern 按前缀删除(pattern 如 soul:book:chapters-by-part:* 转为前缀 soul:book:chapters-by-part:)
|
|||
|
|
func memoryDelPattern(pattern string) {
|
|||
|
|
prefix := strings.TrimSuffix(pattern, "*")
|
|||
|
|
memoryMu.Lock()
|
|||
|
|
defer memoryMu.Unlock()
|
|||
|
|
for k := range memoryData {
|
|||
|
|
if strings.HasPrefix(k, prefix) {
|
|||
|
|
delete(memoryData, k)
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|