msc2946: add federation cache (#2238)

This commit is contained in:
kegsay 2022-03-01 16:32:48 +00:00 committed by GitHub
parent ae840590b6
commit 352e63915f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 59 additions and 14 deletions

View File

@ -0,0 +1,28 @@
package caching
import "github.com/matrix-org/gomatrixserverlib"
const (
SpaceSummaryRoomsCacheName = "space_summary_rooms"
SpaceSummaryRoomsCacheMaxEntries = 100
SpaceSummaryRoomsCacheMutable = true
)
type SpaceSummaryRoomsCache interface {
GetSpaceSummary(roomID string) (r gomatrixserverlib.MSC2946SpacesResponse, ok bool)
StoreSpaceSummary(roomID string, r gomatrixserverlib.MSC2946SpacesResponse)
}
func (c Caches) GetSpaceSummary(roomID string) (r gomatrixserverlib.MSC2946SpacesResponse, ok bool) {
val, found := c.SpaceSummaryRooms.Get(roomID)
if found && val != nil {
if resp, ok := val.(gomatrixserverlib.MSC2946SpacesResponse); ok {
return resp, true
}
}
return r, false
}
func (c Caches) StoreSpaceSummary(roomID string, r gomatrixserverlib.MSC2946SpacesResponse) {
c.SpaceSummaryRooms.Set(roomID, r)
}

View File

@ -10,6 +10,7 @@ type Caches struct {
RoomServerRoomIDs Cache // RoomServerNIDsCache RoomServerRoomIDs Cache // RoomServerNIDsCache
RoomInfos Cache // RoomInfoCache RoomInfos Cache // RoomInfoCache
FederationEvents Cache // FederationEventsCache FederationEvents Cache // FederationEventsCache
SpaceSummaryRooms Cache // SpaceSummaryRoomsCache
} }
// Cache is the interface that an implementation must satisfy. // Cache is the interface that an implementation must satisfy.

View File

@ -55,9 +55,18 @@ func NewInMemoryLRUCache(enablePrometheus bool) (*Caches, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
spaceRooms, err := NewInMemoryLRUCachePartition(
SpaceSummaryRoomsCacheName,
SpaceSummaryRoomsCacheMutable,
SpaceSummaryRoomsCacheMaxEntries,
enablePrometheus,
)
if err != nil {
return nil, err
}
go cacheCleaner( go cacheCleaner(
roomVersions, serverKeys, roomServerRoomIDs, roomVersions, serverKeys, roomServerRoomIDs,
roomInfos, federationEvents, roomInfos, federationEvents, spaceRooms,
) )
return &Caches{ return &Caches{
RoomVersions: roomVersions, RoomVersions: roomVersions,
@ -65,6 +74,7 @@ func NewInMemoryLRUCache(enablePrometheus bool) (*Caches, error) {
RoomServerRoomIDs: roomServerRoomIDs, RoomServerRoomIDs: roomServerRoomIDs,
RoomInfos: roomInfos, RoomInfos: roomInfos,
FederationEvents: federationEvents, FederationEvents: federationEvents,
SpaceSummaryRooms: spaceRooms,
}, nil }, nil
} }

View File

@ -30,6 +30,7 @@ import (
"github.com/gorilla/mux" "github.com/gorilla/mux"
"github.com/matrix-org/dendrite/clientapi/jsonerror" "github.com/matrix-org/dendrite/clientapi/jsonerror"
fs "github.com/matrix-org/dendrite/federationapi/api" fs "github.com/matrix-org/dendrite/federationapi/api"
"github.com/matrix-org/dendrite/internal/caching"
"github.com/matrix-org/dendrite/internal/httputil" "github.com/matrix-org/dendrite/internal/httputil"
roomserver "github.com/matrix-org/dendrite/roomserver/api" roomserver "github.com/matrix-org/dendrite/roomserver/api"
"github.com/matrix-org/dendrite/setup/base" "github.com/matrix-org/dendrite/setup/base"
@ -54,9 +55,9 @@ type MSC2946ClientResponse struct {
// Enable this MSC // Enable this MSC
func Enable( func Enable(
base *base.BaseDendrite, rsAPI roomserver.RoomserverInternalAPI, userAPI userapi.UserInternalAPI, base *base.BaseDendrite, rsAPI roomserver.RoomserverInternalAPI, userAPI userapi.UserInternalAPI,
fsAPI fs.FederationInternalAPI, keyRing gomatrixserverlib.JSONVerifier, fsAPI fs.FederationInternalAPI, keyRing gomatrixserverlib.JSONVerifier, cache caching.SpaceSummaryRoomsCache,
) error { ) error {
clientAPI := httputil.MakeAuthAPI("spaces", userAPI, spacesHandler(rsAPI, fsAPI, base.Cfg.Global.ServerName)) clientAPI := httputil.MakeAuthAPI("spaces", userAPI, spacesHandler(rsAPI, fsAPI, cache, base.Cfg.Global.ServerName))
base.PublicClientAPIMux.Handle("/v1/rooms/{roomID}/hierarchy", clientAPI).Methods(http.MethodGet, http.MethodOptions) base.PublicClientAPIMux.Handle("/v1/rooms/{roomID}/hierarchy", clientAPI).Methods(http.MethodGet, http.MethodOptions)
base.PublicClientAPIMux.Handle("/unstable/org.matrix.msc2946/rooms/{roomID}/hierarchy", clientAPI).Methods(http.MethodGet, http.MethodOptions) base.PublicClientAPIMux.Handle("/unstable/org.matrix.msc2946/rooms/{roomID}/hierarchy", clientAPI).Methods(http.MethodGet, http.MethodOptions)
@ -74,7 +75,7 @@ func Enable(
return util.ErrorResponse(err) return util.ErrorResponse(err)
} }
roomID := params["roomID"] roomID := params["roomID"]
return federatedSpacesHandler(req.Context(), fedReq, roomID, rsAPI, fsAPI, base.Cfg.Global.ServerName) return federatedSpacesHandler(req.Context(), fedReq, roomID, cache, rsAPI, fsAPI, base.Cfg.Global.ServerName)
}, },
) )
base.PublicFederationAPIMux.Handle("/unstable/org.matrix.msc2946/hierarchy/{roomID}", fedAPI).Methods(http.MethodGet) base.PublicFederationAPIMux.Handle("/unstable/org.matrix.msc2946/hierarchy/{roomID}", fedAPI).Methods(http.MethodGet)
@ -84,6 +85,7 @@ func Enable(
func federatedSpacesHandler( func federatedSpacesHandler(
ctx context.Context, fedReq *gomatrixserverlib.FederationRequest, roomID string, ctx context.Context, fedReq *gomatrixserverlib.FederationRequest, roomID string,
cache caching.SpaceSummaryRoomsCache,
rsAPI roomserver.RoomserverInternalAPI, fsAPI fs.FederationInternalAPI, rsAPI roomserver.RoomserverInternalAPI, fsAPI fs.FederationInternalAPI,
thisServer gomatrixserverlib.ServerName, thisServer gomatrixserverlib.ServerName,
) util.JSONResponse { ) util.JSONResponse {
@ -100,6 +102,7 @@ func federatedSpacesHandler(
serverName: fedReq.Origin(), serverName: fedReq.Origin(),
thisServer: thisServer, thisServer: thisServer,
ctx: ctx, ctx: ctx,
cache: cache,
suggestedOnly: u.Query().Get("suggested_only") == "true", suggestedOnly: u.Query().Get("suggested_only") == "true",
limit: 1000, limit: 1000,
// The main difference is that it does not recurse into spaces and does not support pagination. // The main difference is that it does not recurse into spaces and does not support pagination.
@ -115,7 +118,9 @@ func federatedSpacesHandler(
} }
func spacesHandler( func spacesHandler(
rsAPI roomserver.RoomserverInternalAPI, fsAPI fs.FederationInternalAPI, rsAPI roomserver.RoomserverInternalAPI,
fsAPI fs.FederationInternalAPI,
cache caching.SpaceSummaryRoomsCache,
thisServer gomatrixserverlib.ServerName, thisServer gomatrixserverlib.ServerName,
) func(*http.Request, *userapi.Device) util.JSONResponse { ) func(*http.Request, *userapi.Device) util.JSONResponse {
// declared outside the returned handler so it persists between calls // declared outside the returned handler so it persists between calls
@ -138,6 +143,7 @@ func spacesHandler(
caller: device, caller: device,
thisServer: thisServer, thisServer: thisServer,
ctx: req.Context(), ctx: req.Context(),
cache: cache,
rsAPI: rsAPI, rsAPI: rsAPI,
fsAPI: fsAPI, fsAPI: fsAPI,
@ -160,6 +166,7 @@ type walker struct {
rsAPI roomserver.RoomserverInternalAPI rsAPI roomserver.RoomserverInternalAPI
fsAPI fs.FederationInternalAPI fsAPI fs.FederationInternalAPI
ctx context.Context ctx context.Context
cache caching.SpaceSummaryRoomsCache
suggestedOnly bool suggestedOnly bool
limit int limit int
maxDepth int maxDepth int
@ -169,13 +176,6 @@ type walker struct {
mu sync.Mutex mu sync.Mutex
} }
func (w *walker) callerID() string {
if w.caller != nil {
return w.caller.UserID + "|" + w.caller.ID
}
return string(w.serverName)
}
func (w *walker) newPaginationCache() (string, paginationInfo) { func (w *walker) newPaginationCache() (string, paginationInfo) {
p := paginationInfo{ p := paginationInfo{
processed: make(set), processed: make(set),
@ -414,7 +414,12 @@ func (w *walker) federatedRoomInfo(roomID string, vias []string) (*gomatrixserve
if w.caller == nil { if w.caller == nil {
return nil, nil return nil, nil
} }
util.GetLogger(w.ctx).Infof("Querying %s via %+v", roomID, vias) resp, ok := w.cache.GetSpaceSummary(roomID)
if ok {
util.GetLogger(w.ctx).Debugf("Returning cached response for %s", roomID)
return &resp, nil
}
util.GetLogger(w.ctx).Debugf("Querying %s via %+v", roomID, vias)
ctx := context.Background() ctx := context.Background()
// query more of the spaces graph using these servers // query more of the spaces graph using these servers
for _, serverName := range vias { for _, serverName := range vias {
@ -437,6 +442,7 @@ func (w *walker) federatedRoomInfo(roomID string, vias []string) (*gomatrixserve
} }
res.Children[i] = child res.Children[i] = child
} }
w.cache.StoreSpaceSummary(roomID, res)
return &res, nil return &res, nil
} }

View File

@ -42,7 +42,7 @@ func EnableMSC(base *base.BaseDendrite, monolith *setup.Monolith, msc string) er
case "msc2836": case "msc2836":
return msc2836.Enable(base, monolith.RoomserverAPI, monolith.FederationAPI, monolith.UserAPI, monolith.KeyRing) return msc2836.Enable(base, monolith.RoomserverAPI, monolith.FederationAPI, monolith.UserAPI, monolith.KeyRing)
case "msc2946": case "msc2946":
return msc2946.Enable(base, monolith.RoomserverAPI, monolith.UserAPI, monolith.FederationAPI, monolith.KeyRing) return msc2946.Enable(base, monolith.RoomserverAPI, monolith.UserAPI, monolith.FederationAPI, monolith.KeyRing, base.Caches)
case "msc2444": // enabled inside federationapi case "msc2444": // enabled inside federationapi
case "msc2753": // enabled inside clientapi case "msc2753": // enabled inside clientapi
default: default: