chore: refresh gramsrv public release
This commit is contained in:
parent
75cebe8dbf
commit
70b6820474
1274 changed files with 378751 additions and 59919 deletions
76
internal/rpc/projection_cache.go
Normal file
76
internal/rpc/projection_cache.go
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
package rpc
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"telesrv/internal/readmodelcache"
|
||||
)
|
||||
|
||||
// projectionCache 是 RPC 层 per-viewer TTL 投影缓存的统一核心,基于 readmodelcache.Cache。
|
||||
// 4 个结构同形的投影缓存(userFull/peerSettings/channelFull/channelFullBot)收敛到它,
|
||||
// 仅在键类型、值类型、clone、失效维度上不同;TTL 与时钟、LRU 单条驱逐、epoch 守卫均由原语承载。
|
||||
//
|
||||
// 这些投影走「外部构建再写回」模式(LoadEpoch → 在 handler 内构建 → StoreIfEpoch),而非
|
||||
// GetOrLoad:投影需要 ctx、多次往返与富化,无法塞进单个 load 回调。epoch 守卫确保构建期间
|
||||
// 到达的失效不会被 pre-invalidation 快照覆盖(避免陈旧 per-viewer 投影留满一个 TTL)。
|
||||
type projectionCache[K comparable, V any] struct {
|
||||
cache *readmodelcache.Cache[K, V]
|
||||
}
|
||||
|
||||
func newProjectionCache[K comparable, V any](max int, ttl time.Duration, clock func() time.Time, clone func(V) V) *projectionCache[K, V] {
|
||||
return &projectionCache[K, V]{
|
||||
cache: readmodelcache.New[K, V](readmodelcache.Config[K, V]{
|
||||
MaxEntries: max,
|
||||
TTL: ttl,
|
||||
Now: clock,
|
||||
Clone: clone,
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
// Lookup 返回缓存项(TTL 过期视为 miss);clone 由原语在返回边界完成。
|
||||
func (c *projectionCache[K, V]) lookup(key K) (V, bool) {
|
||||
if c == nil {
|
||||
var zero V
|
||||
return zero, false
|
||||
}
|
||||
return c.cache.Peek(key)
|
||||
}
|
||||
|
||||
// storeIfEpoch 仅在 epoch 自 loadEpoch 以来未变时写回外部构建的值。
|
||||
func (c *projectionCache[K, V]) storeIfEpoch(key K, v V, loadEpoch uint64) {
|
||||
if c == nil {
|
||||
return
|
||||
}
|
||||
c.cache.StoreIfEpoch(key, v, loadEpoch)
|
||||
}
|
||||
|
||||
// LoadEpoch 在构建前快照 epoch,与 storeIfEpoch 配对实现外部构建路径的 epoch 守卫。
|
||||
func (c *projectionCache[K, V]) LoadEpoch() uint64 {
|
||||
if c == nil {
|
||||
return 0
|
||||
}
|
||||
return c.cache.LoadEpoch()
|
||||
}
|
||||
|
||||
func (c *projectionCache[K, V]) deleteKey(key K) {
|
||||
if c == nil {
|
||||
return
|
||||
}
|
||||
c.cache.Invalidate(key)
|
||||
}
|
||||
|
||||
func (c *projectionCache[K, V]) deleteWhere(pred func(K) bool) {
|
||||
if c == nil {
|
||||
return
|
||||
}
|
||||
c.cache.InvalidateWhere(pred)
|
||||
}
|
||||
|
||||
// Clear 清空缓存并自增 epoch(listener 重连兜底)。
|
||||
func (c *projectionCache[K, V]) Clear() {
|
||||
if c == nil {
|
||||
return
|
||||
}
|
||||
c.cache.Flush()
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue