aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNeil Alexander <neilalexander@users.noreply.github.com>2020-12-16 12:15:12 +0000
committerGitHub <noreply@github.com>2020-12-16 12:15:12 +0000
commitb891c00b09ed94d0fdfeb449df5e345c67208700 (patch)
treed6be6dbd5f422f3188401121c967fa3472e9097f
parent90571430330afa887912f55fa6a3b329299d927e (diff)
Add RoomInfo cache, remove RoomServerRoomNIDsCache (#1646)
* Add RoomInfo cache, remove RoomServerRoomNID cache, ensure caches are thread-safe * Don't panic if the roomInfo isn't known yet * LRU package is already threadsafe * Use RoomInfo cache to find room version if possible in Events() * Adding comments about RoomInfoCache safety
-rw-r--r--internal/caching/cache_roominfo.go45
-rw-r--r--internal/caching/cache_roomservernids.go25
-rw-r--r--internal/caching/caches.go1
-rw-r--r--internal/caching/impl_inmemorylru.go18
-rw-r--r--roomserver/storage/shared/latest_events_updater.go7
-rw-r--r--roomserver/storage/shared/storage.go33
6 files changed, 88 insertions, 41 deletions
diff --git a/internal/caching/cache_roominfo.go b/internal/caching/cache_roominfo.go
new file mode 100644
index 00000000..f32d6ba9
--- /dev/null
+++ b/internal/caching/cache_roominfo.go
@@ -0,0 +1,45 @@
+package caching
+
+import (
+ "github.com/matrix-org/dendrite/roomserver/types"
+)
+
+// WARNING: This cache is mutable because it's entirely possible that
+// the IsStub or StateSnaphotNID fields can change, even though the
+// room version and room NID fields will not. This is only safe because
+// the RoomInfoCache is used ONLY within the roomserver and because it
+// will be kept up-to-date by the latest events updater. It MUST NOT be
+// used from other components as we currently have no way to invalidate
+// the cache in downstream components.
+
+const (
+ RoomInfoCacheName = "roominfo"
+ RoomInfoCacheMaxEntries = 1024
+ RoomInfoCacheMutable = true
+)
+
+// RoomInfosCache contains the subset of functions needed for
+// a room Info cache. It must only be used from the roomserver only
+// It is not safe for use from other components.
+type RoomInfoCache interface {
+ GetRoomInfo(roomID string) (roomInfo types.RoomInfo, ok bool)
+ StoreRoomInfo(roomID string, roomInfo types.RoomInfo)
+}
+
+// GetRoomInfo must only be called from the roomserver only. It is not
+// safe for use from other components.
+func (c Caches) GetRoomInfo(roomID string) (types.RoomInfo, bool) {
+ val, found := c.RoomInfos.Get(roomID)
+ if found && val != nil {
+ if roomInfo, ok := val.(types.RoomInfo); ok {
+ return roomInfo, true
+ }
+ }
+ return types.RoomInfo{}, false
+}
+
+// StoreRoomInfo must only be called from the roomserver only. It is not
+// safe for use from other components.
+func (c Caches) StoreRoomInfo(roomID string, roomInfo types.RoomInfo) {
+ c.RoomInfos.Set(roomID, roomInfo)
+}
diff --git a/internal/caching/cache_roomservernids.go b/internal/caching/cache_roomservernids.go
index cac59549..bf4fe85e 100644
--- a/internal/caching/cache_roomservernids.go
+++ b/internal/caching/cache_roomservernids.go
@@ -15,10 +15,6 @@ const (
RoomServerEventTypeNIDsCacheMaxEntries = 64
RoomServerEventTypeNIDsCacheMutable = false
- RoomServerRoomNIDsCacheName = "roomserver_room_nids"
- RoomServerRoomNIDsCacheMaxEntries = 1024
- RoomServerRoomNIDsCacheMutable = false
-
RoomServerRoomIDsCacheName = "roomserver_room_ids"
RoomServerRoomIDsCacheMaxEntries = 1024
RoomServerRoomIDsCacheMutable = false
@@ -27,6 +23,7 @@ const (
type RoomServerCaches interface {
RoomServerNIDsCache
RoomVersionCache
+ RoomInfoCache
}
// RoomServerNIDsCache contains the subset of functions needed for
@@ -38,9 +35,6 @@ type RoomServerNIDsCache interface {
GetRoomServerEventTypeNID(eventType string) (types.EventTypeNID, bool)
StoreRoomServerEventTypeNID(eventType string, nid types.EventTypeNID)
- GetRoomServerRoomNID(roomID string) (types.RoomNID, bool)
- StoreRoomServerRoomNID(roomID string, nid types.RoomNID)
-
GetRoomServerRoomID(roomNID types.RoomNID) (string, bool)
StoreRoomServerRoomID(roomNID types.RoomNID, roomID string)
}
@@ -73,21 +67,6 @@ func (c Caches) StoreRoomServerEventTypeNID(eventType string, nid types.EventTyp
c.RoomServerEventTypeNIDs.Set(eventType, nid)
}
-func (c Caches) GetRoomServerRoomNID(roomID string) (types.RoomNID, bool) {
- val, found := c.RoomServerRoomNIDs.Get(roomID)
- if found && val != nil {
- if roomNID, ok := val.(types.RoomNID); ok {
- return roomNID, true
- }
- }
- return 0, false
-}
-
-func (c Caches) StoreRoomServerRoomNID(roomID string, roomNID types.RoomNID) {
- c.RoomServerRoomNIDs.Set(roomID, roomNID)
- c.RoomServerRoomIDs.Set(strconv.Itoa(int(roomNID)), roomID)
-}
-
func (c Caches) GetRoomServerRoomID(roomNID types.RoomNID) (string, bool) {
val, found := c.RoomServerRoomIDs.Get(strconv.Itoa(int(roomNID)))
if found && val != nil {
@@ -99,5 +78,5 @@ func (c Caches) GetRoomServerRoomID(roomNID types.RoomNID) (string, bool) {
}
func (c Caches) StoreRoomServerRoomID(roomNID types.RoomNID, roomID string) {
- c.StoreRoomServerRoomNID(roomID, roomNID)
+ c.RoomServerRoomIDs.Set(strconv.Itoa(int(roomNID)), roomID)
}
diff --git a/internal/caching/caches.go b/internal/caching/caches.go
index e7b7f550..f04d05d4 100644
--- a/internal/caching/caches.go
+++ b/internal/caching/caches.go
@@ -10,6 +10,7 @@ type Caches struct {
RoomServerEventTypeNIDs Cache // RoomServerNIDsCache
RoomServerRoomNIDs Cache // RoomServerNIDsCache
RoomServerRoomIDs Cache // RoomServerNIDsCache
+ RoomInfos Cache // RoomInfoCache
FederationEvents Cache // FederationEventsCache
}
diff --git a/internal/caching/impl_inmemorylru.go b/internal/caching/impl_inmemorylru.go
index f05e8f3c..cf05a8b5 100644
--- a/internal/caching/impl_inmemorylru.go
+++ b/internal/caching/impl_inmemorylru.go
@@ -45,19 +45,19 @@ func NewInMemoryLRUCache(enablePrometheus bool) (*Caches, error) {
if err != nil {
return nil, err
}
- roomServerRoomNIDs, err := NewInMemoryLRUCachePartition(
- RoomServerRoomNIDsCacheName,
- RoomServerRoomNIDsCacheMutable,
- RoomServerRoomNIDsCacheMaxEntries,
+ roomServerRoomIDs, err := NewInMemoryLRUCachePartition(
+ RoomServerRoomIDsCacheName,
+ RoomServerRoomIDsCacheMutable,
+ RoomServerRoomIDsCacheMaxEntries,
enablePrometheus,
)
if err != nil {
return nil, err
}
- roomServerRoomIDs, err := NewInMemoryLRUCachePartition(
- RoomServerRoomIDsCacheName,
- RoomServerRoomIDsCacheMutable,
- RoomServerRoomIDsCacheMaxEntries,
+ roomInfos, err := NewInMemoryLRUCachePartition(
+ RoomInfoCacheName,
+ RoomInfoCacheMutable,
+ RoomInfoCacheMaxEntries,
enablePrometheus,
)
if err != nil {
@@ -77,8 +77,8 @@ func NewInMemoryLRUCache(enablePrometheus bool) (*Caches, error) {
ServerKeys: serverKeys,
RoomServerStateKeyNIDs: roomServerStateKeyNIDs,
RoomServerEventTypeNIDs: roomServerEventTypeNIDs,
- RoomServerRoomNIDs: roomServerRoomNIDs,
RoomServerRoomIDs: roomServerRoomIDs,
+ RoomInfos: roomInfos,
FederationEvents: federationEvents,
}, nil
}
diff --git a/roomserver/storage/shared/latest_events_updater.go b/roomserver/storage/shared/latest_events_updater.go
index 8825dc46..36865081 100644
--- a/roomserver/storage/shared/latest_events_updater.go
+++ b/roomserver/storage/shared/latest_events_updater.go
@@ -105,6 +105,13 @@ func (u *LatestEventsUpdater) SetLatestEvents(
if err := u.d.RoomsTable.UpdateLatestEventNIDs(u.ctx, txn, roomNID, eventNIDs, lastEventNIDSent, currentStateSnapshotNID); err != nil {
return fmt.Errorf("u.d.RoomsTable.updateLatestEventNIDs: %w", err)
}
+ if roomID, ok := u.d.Cache.GetRoomServerRoomID(roomNID); ok {
+ if roomInfo, ok := u.d.Cache.GetRoomInfo(roomID); ok {
+ roomInfo.StateSnapshotNID = currentStateSnapshotNID
+ roomInfo.IsStub = false
+ u.d.Cache.StoreRoomInfo(roomID, roomInfo)
+ }
+ }
return nil
})
}
diff --git a/roomserver/storage/shared/storage.go b/roomserver/storage/shared/storage.go
index d61fa61d..b4d9d562 100644
--- a/roomserver/storage/shared/storage.go
+++ b/roomserver/storage/shared/storage.go
@@ -124,7 +124,15 @@ func (d *Database) StateEntriesForTuples(
}
func (d *Database) RoomInfo(ctx context.Context, roomID string) (*types.RoomInfo, error) {
- return d.RoomsTable.SelectRoomInfo(ctx, roomID)
+ if roomInfo, ok := d.Cache.GetRoomInfo(roomID); ok {
+ return &roomInfo, nil
+ }
+ roomInfo, err := d.RoomsTable.SelectRoomInfo(ctx, roomID)
+ if err == nil && roomInfo != nil {
+ d.Cache.StoreRoomServerRoomID(roomInfo.RoomNID, roomID)
+ d.Cache.StoreRoomInfo(roomID, *roomInfo)
+ }
+ return roomInfo, err
}
func (d *Database) AddState(
@@ -322,14 +330,24 @@ func (d *Database) Events(
for _, n := range roomNIDs {
uniqueRoomNIDs[n] = struct{}{}
}
- roomNIDList := make([]types.RoomNID, 0, len(uniqueRoomNIDs))
+ roomVersions := make(map[types.RoomNID]gomatrixserverlib.RoomVersion)
+ fetchNIDList := make([]types.RoomNID, 0, len(uniqueRoomNIDs))
for n := range uniqueRoomNIDs {
- roomNIDList = append(roomNIDList, n)
+ if roomID, ok := d.Cache.GetRoomServerRoomID(n); ok {
+ if roomInfo, ok := d.Cache.GetRoomInfo(roomID); ok {
+ roomVersions[n] = roomInfo.RoomVersion
+ continue
+ }
+ }
+ fetchNIDList = append(fetchNIDList, n)
}
- roomVersions, err := d.RoomsTable.SelectRoomVersionsForRoomNIDs(ctx, roomNIDList)
+ dbRoomVersions, err := d.RoomsTable.SelectRoomVersionsForRoomNIDs(ctx, fetchNIDList)
if err != nil {
return nil, err
}
+ for n, v := range dbRoomVersions {
+ roomVersions[n] = v
+ }
results := make([]types.Event, len(eventJSONs))
for i, eventJSON := range eventJSONs {
result := &results[i]
@@ -556,8 +574,8 @@ func (d *Database) assignRoomNID(
ctx context.Context, txn *sql.Tx,
roomID string, roomVersion gomatrixserverlib.RoomVersion,
) (types.RoomNID, error) {
- if roomNID, ok := d.Cache.GetRoomServerRoomNID(roomID); ok {
- return roomNID, nil
+ if roomInfo, ok := d.Cache.GetRoomInfo(roomID); ok {
+ return roomInfo.RoomNID, nil
}
// Check if we already have a numeric ID in the database.
roomNID, err := d.RoomsTable.SelectRoomNID(ctx, txn, roomID)
@@ -569,9 +587,6 @@ func (d *Database) assignRoomNID(
roomNID, err = d.RoomsTable.SelectRoomNID(ctx, txn, roomID)
}
}
- if err == nil {
- d.Cache.StoreRoomServerRoomNID(roomID, roomNID)
- }
return roomNID, err
}