feat: add redis cache and fanout support
This commit is contained in:
@@ -0,0 +1,85 @@
|
||||
package store
|
||||
|
||||
import (
|
||||
"sort"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/tinode/chat/server/store/types"
|
||||
)
|
||||
|
||||
const configCacheTTL = time.Minute
|
||||
|
||||
type configCacheEntry[T any] struct {
|
||||
value T
|
||||
expiresAt time.Time
|
||||
}
|
||||
|
||||
type configCache[T any] struct {
|
||||
mu sync.RWMutex
|
||||
items map[string]configCacheEntry[T]
|
||||
}
|
||||
|
||||
func newConfigCache[T any]() *configCache[T] {
|
||||
return &configCache[T]{items: make(map[string]configCacheEntry[T])}
|
||||
}
|
||||
|
||||
func (c *configCache[T]) get(key string) (T, bool) {
|
||||
var zero T
|
||||
c.mu.RLock()
|
||||
entry, ok := c.items[key]
|
||||
c.mu.RUnlock()
|
||||
if !ok || time.Now().After(entry.expiresAt) {
|
||||
return zero, false
|
||||
}
|
||||
return entry.value, true
|
||||
}
|
||||
|
||||
func (c *configCache[T]) set(key string, value T) {
|
||||
c.mu.Lock()
|
||||
c.items[key] = configCacheEntry[T]{value: value, expiresAt: time.Now().Add(configCacheTTL)}
|
||||
c.mu.Unlock()
|
||||
}
|
||||
|
||||
var (
|
||||
tenantByCodeCache = newConfigCache[*types.Tenant]()
|
||||
tenantByIDCache = newConfigCache[*types.Tenant]()
|
||||
registrationSMSCache = newConfigCache[bool]()
|
||||
thirdPartyConfigCache = newConfigCache[map[string]string]()
|
||||
thirdPartyConfigAllKeys = "*"
|
||||
)
|
||||
|
||||
func cloneTenant(t *types.Tenant) *types.Tenant {
|
||||
if t == nil {
|
||||
return nil
|
||||
}
|
||||
cp := *t
|
||||
return &cp
|
||||
}
|
||||
|
||||
func cloneStringMap(src map[string]string) map[string]string {
|
||||
if src == nil {
|
||||
return nil
|
||||
}
|
||||
dst := make(map[string]string, len(src))
|
||||
for k, v := range src {
|
||||
dst[k] = v
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
func thirdPartyCacheKey(group string, keys ...string) string {
|
||||
group = strings.TrimSpace(group)
|
||||
if len(keys) == 0 {
|
||||
return group + ":" + thirdPartyConfigAllKeys
|
||||
}
|
||||
normalized := make([]string, 0, len(keys))
|
||||
for _, key := range keys {
|
||||
if key = strings.TrimSpace(key); key != "" {
|
||||
normalized = append(normalized, key)
|
||||
}
|
||||
}
|
||||
sort.Strings(normalized)
|
||||
return group + ":" + strings.Join(normalized, ",")
|
||||
}
|
||||
Reference in New Issue
Block a user