Files
im_server/server/store/config_cache.go
T

86 lines
1.8 KiB
Go

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