mirror of
https://github.com/matrix-org/dendrite
synced 2024-12-14 16:03:50 +01:00
Allow specifying max age for caches (#2239)
* Allow specifying max age for caches * Evict cache entry if it's found to be stale when we call Get * Fix bugs
This commit is contained in:
parent
726529fe99
commit
bb2380c254
7 changed files with 48 additions and 5 deletions
|
@ -10,6 +10,7 @@ const (
|
||||||
FederationEventCacheName = "federation_event"
|
FederationEventCacheName = "federation_event"
|
||||||
FederationEventCacheMaxEntries = 256
|
FederationEventCacheMaxEntries = 256
|
||||||
FederationEventCacheMutable = true // to allow use of Unset only
|
FederationEventCacheMutable = true // to allow use of Unset only
|
||||||
|
FederationEventCacheMaxAge = CacheNoMaxAge
|
||||||
)
|
)
|
||||||
|
|
||||||
// FederationCache contains the subset of functions needed for
|
// FederationCache contains the subset of functions needed for
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
package caching
|
package caching
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/matrix-org/dendrite/roomserver/types"
|
"github.com/matrix-org/dendrite/roomserver/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -16,6 +18,7 @@ const (
|
||||||
RoomInfoCacheName = "roominfo"
|
RoomInfoCacheName = "roominfo"
|
||||||
RoomInfoCacheMaxEntries = 1024
|
RoomInfoCacheMaxEntries = 1024
|
||||||
RoomInfoCacheMutable = true
|
RoomInfoCacheMutable = true
|
||||||
|
RoomInfoCacheMaxAge = time.Minute * 5
|
||||||
)
|
)
|
||||||
|
|
||||||
// RoomInfosCache contains the subset of functions needed for
|
// RoomInfosCache contains the subset of functions needed for
|
||||||
|
|
|
@ -10,6 +10,7 @@ const (
|
||||||
RoomServerRoomIDsCacheName = "roomserver_room_ids"
|
RoomServerRoomIDsCacheName = "roomserver_room_ids"
|
||||||
RoomServerRoomIDsCacheMaxEntries = 1024
|
RoomServerRoomIDsCacheMaxEntries = 1024
|
||||||
RoomServerRoomIDsCacheMutable = false
|
RoomServerRoomIDsCacheMutable = false
|
||||||
|
RoomServerRoomIDsCacheMaxAge = CacheNoMaxAge
|
||||||
)
|
)
|
||||||
|
|
||||||
type RoomServerCaches interface {
|
type RoomServerCaches interface {
|
||||||
|
|
|
@ -6,6 +6,7 @@ const (
|
||||||
RoomVersionCacheName = "room_versions"
|
RoomVersionCacheName = "room_versions"
|
||||||
RoomVersionCacheMaxEntries = 1024
|
RoomVersionCacheMaxEntries = 1024
|
||||||
RoomVersionCacheMutable = false
|
RoomVersionCacheMutable = false
|
||||||
|
RoomVersionCacheMaxAge = CacheNoMaxAge
|
||||||
)
|
)
|
||||||
|
|
||||||
// RoomVersionsCache contains the subset of functions needed for
|
// RoomVersionsCache contains the subset of functions needed for
|
||||||
|
|
|
@ -10,6 +10,7 @@ const (
|
||||||
ServerKeyCacheName = "server_key"
|
ServerKeyCacheName = "server_key"
|
||||||
ServerKeyCacheMaxEntries = 4096
|
ServerKeyCacheMaxEntries = 4096
|
||||||
ServerKeyCacheMutable = true
|
ServerKeyCacheMutable = true
|
||||||
|
ServerKeyCacheMaxAge = CacheNoMaxAge
|
||||||
)
|
)
|
||||||
|
|
||||||
// ServerKeyCache contains the subset of functions needed for
|
// ServerKeyCache contains the subset of functions needed for
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
package caching
|
package caching
|
||||||
|
|
||||||
|
import "time"
|
||||||
|
|
||||||
// Caches contains a set of references to caches. They may be
|
// Caches contains a set of references to caches. They may be
|
||||||
// different implementations as long as they satisfy the Cache
|
// different implementations as long as they satisfy the Cache
|
||||||
// interface.
|
// interface.
|
||||||
|
@ -19,3 +21,5 @@ type Cache interface {
|
||||||
Set(key string, value interface{})
|
Set(key string, value interface{})
|
||||||
Unset(key string)
|
Unset(key string)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const CacheNoMaxAge = time.Duration(0)
|
||||||
|
|
|
@ -14,6 +14,7 @@ func NewInMemoryLRUCache(enablePrometheus bool) (*Caches, error) {
|
||||||
RoomVersionCacheName,
|
RoomVersionCacheName,
|
||||||
RoomVersionCacheMutable,
|
RoomVersionCacheMutable,
|
||||||
RoomVersionCacheMaxEntries,
|
RoomVersionCacheMaxEntries,
|
||||||
|
RoomVersionCacheMaxAge,
|
||||||
enablePrometheus,
|
enablePrometheus,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -23,6 +24,7 @@ func NewInMemoryLRUCache(enablePrometheus bool) (*Caches, error) {
|
||||||
ServerKeyCacheName,
|
ServerKeyCacheName,
|
||||||
ServerKeyCacheMutable,
|
ServerKeyCacheMutable,
|
||||||
ServerKeyCacheMaxEntries,
|
ServerKeyCacheMaxEntries,
|
||||||
|
ServerKeyCacheMaxAge,
|
||||||
enablePrometheus,
|
enablePrometheus,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -32,6 +34,7 @@ func NewInMemoryLRUCache(enablePrometheus bool) (*Caches, error) {
|
||||||
RoomServerRoomIDsCacheName,
|
RoomServerRoomIDsCacheName,
|
||||||
RoomServerRoomIDsCacheMutable,
|
RoomServerRoomIDsCacheMutable,
|
||||||
RoomServerRoomIDsCacheMaxEntries,
|
RoomServerRoomIDsCacheMaxEntries,
|
||||||
|
RoomServerRoomIDsCacheMaxAge,
|
||||||
enablePrometheus,
|
enablePrometheus,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -41,6 +44,7 @@ func NewInMemoryLRUCache(enablePrometheus bool) (*Caches, error) {
|
||||||
RoomInfoCacheName,
|
RoomInfoCacheName,
|
||||||
RoomInfoCacheMutable,
|
RoomInfoCacheMutable,
|
||||||
RoomInfoCacheMaxEntries,
|
RoomInfoCacheMaxEntries,
|
||||||
|
RoomInfoCacheMaxAge,
|
||||||
enablePrometheus,
|
enablePrometheus,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -50,6 +54,7 @@ func NewInMemoryLRUCache(enablePrometheus bool) (*Caches, error) {
|
||||||
FederationEventCacheName,
|
FederationEventCacheName,
|
||||||
FederationEventCacheMutable,
|
FederationEventCacheMutable,
|
||||||
FederationEventCacheMaxEntries,
|
FederationEventCacheMaxEntries,
|
||||||
|
FederationEventCacheMaxAge,
|
||||||
enablePrometheus,
|
enablePrometheus,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -96,15 +101,22 @@ type InMemoryLRUCachePartition struct {
|
||||||
name string
|
name string
|
||||||
mutable bool
|
mutable bool
|
||||||
maxEntries int
|
maxEntries int
|
||||||
|
maxAge time.Duration
|
||||||
lru *lru.Cache
|
lru *lru.Cache
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewInMemoryLRUCachePartition(name string, mutable bool, maxEntries int, enablePrometheus bool) (*InMemoryLRUCachePartition, error) {
|
type inMemoryLRUCacheEntry struct {
|
||||||
|
value interface{}
|
||||||
|
created time.Time
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewInMemoryLRUCachePartition(name string, mutable bool, maxEntries int, maxAge time.Duration, enablePrometheus bool) (*InMemoryLRUCachePartition, error) {
|
||||||
var err error
|
var err error
|
||||||
cache := InMemoryLRUCachePartition{
|
cache := InMemoryLRUCachePartition{
|
||||||
name: name,
|
name: name,
|
||||||
mutable: mutable,
|
mutable: mutable,
|
||||||
maxEntries: maxEntries,
|
maxEntries: maxEntries,
|
||||||
|
maxAge: maxAge,
|
||||||
}
|
}
|
||||||
cache.lru, err = lru.New(maxEntries)
|
cache.lru, err = lru.New(maxEntries)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -124,11 +136,16 @@ func NewInMemoryLRUCachePartition(name string, mutable bool, maxEntries int, ena
|
||||||
|
|
||||||
func (c *InMemoryLRUCachePartition) Set(key string, value interface{}) {
|
func (c *InMemoryLRUCachePartition) Set(key string, value interface{}) {
|
||||||
if !c.mutable {
|
if !c.mutable {
|
||||||
if peek, ok := c.lru.Peek(key); ok && peek != value {
|
if peek, ok := c.lru.Peek(key); ok {
|
||||||
panic(fmt.Sprintf("invalid use of immutable cache tries to mutate existing value of %q", key))
|
if entry, ok := peek.(*inMemoryLRUCacheEntry); ok && entry.value != value {
|
||||||
|
panic(fmt.Sprintf("invalid use of immutable cache tries to mutate existing value of %q", key))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
c.lru.Add(key, value)
|
c.lru.Add(key, &inMemoryLRUCacheEntry{
|
||||||
|
value: value,
|
||||||
|
created: time.Now(),
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *InMemoryLRUCachePartition) Unset(key string) {
|
func (c *InMemoryLRUCachePartition) Unset(key string) {
|
||||||
|
@ -139,5 +156,20 @@ func (c *InMemoryLRUCachePartition) Unset(key string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *InMemoryLRUCachePartition) Get(key string) (value interface{}, ok bool) {
|
func (c *InMemoryLRUCachePartition) Get(key string) (value interface{}, ok bool) {
|
||||||
return c.lru.Get(key)
|
v, ok := c.lru.Get(key)
|
||||||
|
if !ok {
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
entry, ok := v.(*inMemoryLRUCacheEntry)
|
||||||
|
switch {
|
||||||
|
case ok && c.maxAge == CacheNoMaxAge:
|
||||||
|
return entry.value, ok // There's no maximum age policy
|
||||||
|
case ok && time.Since(entry.created) < c.maxAge:
|
||||||
|
return entry.value, ok // The value for the key isn't stale
|
||||||
|
default:
|
||||||
|
// Either the key was found and it was stale, or the key
|
||||||
|
// wasn't found at all
|
||||||
|
c.lru.Remove(key)
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue