mirror of
https://github.com/matrix-org/dendrite.git
synced 2025-12-21 05:43:09 -06:00
Initial work on roomserver NID caches
This commit is contained in:
parent
733abe912b
commit
6b5be72503
79
internal/caching/cache_roomservernids.go
Normal file
79
internal/caching/cache_roomservernids.go
Normal file
|
|
@ -0,0 +1,79 @@
|
||||||
|
package caching
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/matrix-org/dendrite/roomserver/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
RoomServerStateKeyNIDsCacheName = "roomserver_statekey_nids"
|
||||||
|
RoomServerStateKeyNIDsCacheMaxEntries = 1024
|
||||||
|
RoomServerStateKeyNIDsCacheMutable = false
|
||||||
|
|
||||||
|
RoomServerEventTypeNIDsCacheName = "roomserver_eventtype_nids"
|
||||||
|
RoomServerEventTypeNIDsCacheMaxEntries = 64
|
||||||
|
RoomServerEventTypeNIDsCacheMutable = false
|
||||||
|
|
||||||
|
RoomServerRoomNIDsCacheName = "roomserver_room_nids"
|
||||||
|
RoomServerRoomNIDsCacheMaxEntries = 1024
|
||||||
|
RoomServerRoomNIDsCacheMutable = false
|
||||||
|
)
|
||||||
|
|
||||||
|
type RoomServerCaches interface {
|
||||||
|
RoomServerNIDsCache
|
||||||
|
RoomVersionCache
|
||||||
|
}
|
||||||
|
|
||||||
|
// RoomServerNIDsCache contains the subset of functions needed for
|
||||||
|
// a roomserver NID cache.
|
||||||
|
type RoomServerNIDsCache interface {
|
||||||
|
GetRoomServerStateKeyNID(stateKey string) (types.EventStateKeyNID, bool)
|
||||||
|
StoreRoomServerStateKeyNID(stateKey string, nid types.EventStateKeyNID)
|
||||||
|
|
||||||
|
GetRoomServerEventTypeNID(eventType string) (types.EventTypeNID, bool)
|
||||||
|
StoreRoomServerEventTypeNID(eventType string, nid types.EventTypeNID)
|
||||||
|
|
||||||
|
GetRoomServerRoomNID(roomID string) (types.RoomNID, bool)
|
||||||
|
StoreRoomServerRoomNID(roomID string, nid types.RoomNID)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c Caches) GetRoomServerStateKeyNID(stateKey string) (types.EventStateKeyNID, bool) {
|
||||||
|
val, found := c.RoomServerStateKeyNIDs.Get(stateKey)
|
||||||
|
if found && val != nil {
|
||||||
|
if stateKeyNID, ok := val.(types.EventStateKeyNID); ok {
|
||||||
|
return stateKeyNID, true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0, false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c Caches) StoreRoomServerStateKeyNID(stateKey string, nid types.EventStateKeyNID) {
|
||||||
|
c.RoomVersions.Set(stateKey, nid)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c Caches) GetRoomServerEventTypeNID(eventType string) (types.EventTypeNID, bool) {
|
||||||
|
val, found := c.RoomServerEventTypeNIDs.Get(eventType)
|
||||||
|
if found && val != nil {
|
||||||
|
if eventTypeNID, ok := val.(types.EventTypeNID); ok {
|
||||||
|
return eventTypeNID, true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0, false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c Caches) StoreRoomServerEventTypeNID(eventType string, nid types.EventTypeNID) {
|
||||||
|
c.RoomVersions.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, nid types.RoomNID) {
|
||||||
|
c.RoomVersions.Set(roomID, nid)
|
||||||
|
}
|
||||||
|
|
@ -4,8 +4,11 @@ package caching
|
||||||
// different implementations as long as they satisfy the Cache
|
// different implementations as long as they satisfy the Cache
|
||||||
// interface.
|
// interface.
|
||||||
type Caches struct {
|
type Caches struct {
|
||||||
RoomVersions Cache // implements RoomVersionCache
|
RoomVersions Cache // RoomVersionCache
|
||||||
ServerKeys Cache // implements ServerKeyCache
|
ServerKeys Cache // ServerKeyCache
|
||||||
|
RoomServerStateKeyNIDs Cache // RoomServerNIDsCache
|
||||||
|
RoomServerEventTypeNIDs Cache // RoomServerNIDsCache
|
||||||
|
RoomServerRoomNIDs Cache // RoomServerNIDsCache
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cache is the interface that an implementation must satisfy.
|
// Cache is the interface that an implementation must satisfy.
|
||||||
|
|
|
||||||
|
|
@ -27,9 +27,39 @@ func NewInMemoryLRUCache(enablePrometheus bool) (*Caches, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
roomServerStateKeyNIDs, err := NewInMemoryLRUCachePartition(
|
||||||
|
RoomServerStateKeyNIDsCacheName,
|
||||||
|
RoomServerStateKeyNIDsCacheMutable,
|
||||||
|
RoomServerStateKeyNIDsCacheMaxEntries,
|
||||||
|
enablePrometheus,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
roomServerEventTypeNIDs, err := NewInMemoryLRUCachePartition(
|
||||||
|
RoomServerEventTypeNIDsCacheName,
|
||||||
|
RoomServerEventTypeNIDsCacheMutable,
|
||||||
|
RoomServerEventTypeNIDsCacheMaxEntries,
|
||||||
|
enablePrometheus,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
roomServerRoomNIDs, err := NewInMemoryLRUCachePartition(
|
||||||
|
RoomServerRoomNIDsCacheName,
|
||||||
|
RoomServerRoomNIDsCacheMutable,
|
||||||
|
RoomServerRoomNIDsCacheMaxEntries,
|
||||||
|
enablePrometheus,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
return &Caches{
|
return &Caches{
|
||||||
RoomVersions: roomVersions,
|
RoomVersions: roomVersions,
|
||||||
ServerKeys: serverKeys,
|
ServerKeys: serverKeys,
|
||||||
|
RoomServerStateKeyNIDs: roomServerStateKeyNIDs,
|
||||||
|
RoomServerEventTypeNIDs: roomServerEventTypeNIDs,
|
||||||
|
RoomServerRoomNIDs: roomServerRoomNIDs,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ type RoomserverInternalAPI struct {
|
||||||
DB storage.Database
|
DB storage.Database
|
||||||
Cfg *config.RoomServer
|
Cfg *config.RoomServer
|
||||||
Producer sarama.SyncProducer
|
Producer sarama.SyncProducer
|
||||||
Cache caching.RoomVersionCache
|
Cache caching.RoomServerCaches
|
||||||
ServerName gomatrixserverlib.ServerName
|
ServerName gomatrixserverlib.ServerName
|
||||||
KeyRing gomatrixserverlib.JSONVerifier
|
KeyRing gomatrixserverlib.JSONVerifier
|
||||||
FedClient *gomatrixserverlib.FederationClient
|
FedClient *gomatrixserverlib.FederationClient
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@ package postgres
|
||||||
import (
|
import (
|
||||||
"database/sql"
|
"database/sql"
|
||||||
|
|
||||||
|
"github.com/matrix-org/dendrite/internal/caching"
|
||||||
"github.com/matrix-org/dendrite/internal/config"
|
"github.com/matrix-org/dendrite/internal/config"
|
||||||
"github.com/matrix-org/dendrite/internal/sqlutil"
|
"github.com/matrix-org/dendrite/internal/sqlutil"
|
||||||
|
|
||||||
|
|
@ -33,7 +34,7 @@ type Database struct {
|
||||||
|
|
||||||
// Open a postgres database.
|
// Open a postgres database.
|
||||||
// nolint: gocyclo
|
// nolint: gocyclo
|
||||||
func Open(dbProperties *config.DatabaseOptions) (*Database, error) {
|
func Open(dbProperties *config.DatabaseOptions, cache caching.RoomServerCaches) (*Database, error) {
|
||||||
var d Database
|
var d Database
|
||||||
var db *sql.DB
|
var db *sql.DB
|
||||||
var err error
|
var err error
|
||||||
|
|
@ -98,6 +99,7 @@ func Open(dbProperties *config.DatabaseOptions) (*Database, error) {
|
||||||
}
|
}
|
||||||
d.Database = shared.Database{
|
d.Database = shared.Database{
|
||||||
DB: db,
|
DB: db,
|
||||||
|
Cache: cache,
|
||||||
Writer: sqlutil.NewDummyWriter(),
|
Writer: sqlutil.NewDummyWriter(),
|
||||||
EventTypesTable: eventTypes,
|
EventTypesTable: eventTypes,
|
||||||
EventStateKeysTable: eventStateKeys,
|
EventStateKeysTable: eventStateKeys,
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/matrix-org/dendrite/internal/caching"
|
||||||
"github.com/matrix-org/dendrite/internal/sqlutil"
|
"github.com/matrix-org/dendrite/internal/sqlutil"
|
||||||
"github.com/matrix-org/dendrite/roomserver/api"
|
"github.com/matrix-org/dendrite/roomserver/api"
|
||||||
"github.com/matrix-org/dendrite/roomserver/storage/tables"
|
"github.com/matrix-org/dendrite/roomserver/storage/tables"
|
||||||
|
|
@ -27,6 +28,7 @@ const redactionsArePermanent = false
|
||||||
|
|
||||||
type Database struct {
|
type Database struct {
|
||||||
DB *sql.DB
|
DB *sql.DB
|
||||||
|
Cache caching.RoomServerCaches
|
||||||
Writer sqlutil.Writer
|
Writer sqlutil.Writer
|
||||||
EventsTable tables.Events
|
EventsTable tables.Events
|
||||||
EventJSONTable tables.EventJSON
|
EventJSONTable tables.EventJSON
|
||||||
|
|
@ -51,7 +53,25 @@ func (d *Database) SupportsConcurrentRoomInputs() bool {
|
||||||
func (d *Database) EventTypeNIDs(
|
func (d *Database) EventTypeNIDs(
|
||||||
ctx context.Context, eventTypes []string,
|
ctx context.Context, eventTypes []string,
|
||||||
) (map[string]types.EventTypeNID, error) {
|
) (map[string]types.EventTypeNID, error) {
|
||||||
return d.EventTypesTable.BulkSelectEventTypeNID(ctx, eventTypes)
|
result := make(map[string]types.EventTypeNID)
|
||||||
|
remaining := []string{}
|
||||||
|
for _, eventType := range eventTypes {
|
||||||
|
if nid, ok := d.Cache.GetRoomServerEventTypeNID(eventType); ok {
|
||||||
|
result[eventType] = nid
|
||||||
|
} else {
|
||||||
|
remaining = append(remaining, eventType)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(remaining) > 0 {
|
||||||
|
nids, err := d.EventTypesTable.BulkSelectEventTypeNID(ctx, remaining)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
for eventType, nid := range nids {
|
||||||
|
result[eventType] = nid
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Database) EventStateKeys(
|
func (d *Database) EventStateKeys(
|
||||||
|
|
@ -63,7 +83,25 @@ func (d *Database) EventStateKeys(
|
||||||
func (d *Database) EventStateKeyNIDs(
|
func (d *Database) EventStateKeyNIDs(
|
||||||
ctx context.Context, eventStateKeys []string,
|
ctx context.Context, eventStateKeys []string,
|
||||||
) (map[string]types.EventStateKeyNID, error) {
|
) (map[string]types.EventStateKeyNID, error) {
|
||||||
return d.EventStateKeysTable.BulkSelectEventStateKeyNID(ctx, eventStateKeys)
|
result := make(map[string]types.EventStateKeyNID)
|
||||||
|
remaining := []string{}
|
||||||
|
for _, eventStateKey := range eventStateKeys {
|
||||||
|
if nid, ok := d.Cache.GetRoomServerStateKeyNID(eventStateKey); ok {
|
||||||
|
result[eventStateKey] = nid
|
||||||
|
} else {
|
||||||
|
remaining = append(remaining, eventStateKey)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(remaining) > 0 {
|
||||||
|
nids, err := d.EventStateKeysTable.BulkSelectEventStateKeyNID(ctx, remaining)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
for eventStateKey, nid := range nids {
|
||||||
|
result[eventStateKey] = nid
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Database) StateEntriesForEventIDs(
|
func (d *Database) StateEntriesForEventIDs(
|
||||||
|
|
@ -157,6 +195,9 @@ func (d *Database) EventsFromIDs(ctx context.Context, eventIDs []string) ([]type
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Database) RoomNID(ctx context.Context, roomID string) (types.RoomNID, error) {
|
func (d *Database) RoomNID(ctx context.Context, roomID string) (types.RoomNID, error) {
|
||||||
|
if nid, ok := d.Cache.GetRoomServerRoomNID(roomID); ok {
|
||||||
|
return nid, nil
|
||||||
|
}
|
||||||
roomNID, err := d.RoomsTable.SelectRoomNID(ctx, nil, roomID)
|
roomNID, err := d.RoomsTable.SelectRoomNID(ctx, nil, roomID)
|
||||||
if err == sql.ErrNoRows {
|
if err == sql.ErrNoRows {
|
||||||
return 0, nil
|
return 0, nil
|
||||||
|
|
@ -165,10 +206,14 @@ func (d *Database) RoomNID(ctx context.Context, roomID string) (types.RoomNID, e
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Database) RoomNIDExcludingStubs(ctx context.Context, roomID string) (roomNID types.RoomNID, err error) {
|
func (d *Database) RoomNIDExcludingStubs(ctx context.Context, roomID string) (roomNID types.RoomNID, err error) {
|
||||||
|
if nid, ok := d.Cache.GetRoomServerRoomNID(roomID); ok {
|
||||||
|
roomNID = nid
|
||||||
|
} else {
|
||||||
roomNID, err = d.RoomNID(ctx, roomID)
|
roomNID, err = d.RoomNID(ctx, roomID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
}
|
||||||
latestEvents, _, err := d.RoomsTable.SelectLatestEventNIDs(ctx, nil, roomNID)
|
latestEvents, _, err := d.RoomsTable.SelectLatestEventNIDs(ctx, nil, roomNID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"database/sql"
|
"database/sql"
|
||||||
|
|
||||||
|
"github.com/matrix-org/dendrite/internal/caching"
|
||||||
"github.com/matrix-org/dendrite/internal/config"
|
"github.com/matrix-org/dendrite/internal/config"
|
||||||
"github.com/matrix-org/dendrite/internal/sqlutil"
|
"github.com/matrix-org/dendrite/internal/sqlutil"
|
||||||
"github.com/matrix-org/dendrite/roomserver/storage/shared"
|
"github.com/matrix-org/dendrite/roomserver/storage/shared"
|
||||||
|
|
@ -46,7 +47,7 @@ type Database struct {
|
||||||
|
|
||||||
// Open a sqlite database.
|
// Open a sqlite database.
|
||||||
// nolint: gocyclo
|
// nolint: gocyclo
|
||||||
func Open(dbProperties *config.DatabaseOptions) (*Database, error) {
|
func Open(dbProperties *config.DatabaseOptions, cache caching.RoomServerCaches) (*Database, error) {
|
||||||
var d Database
|
var d Database
|
||||||
var err error
|
var err error
|
||||||
if d.db, err = sqlutil.Open(dbProperties); err != nil {
|
if d.db, err = sqlutil.Open(dbProperties); err != nil {
|
||||||
|
|
@ -120,6 +121,7 @@ func Open(dbProperties *config.DatabaseOptions) (*Database, error) {
|
||||||
}
|
}
|
||||||
d.Database = shared.Database{
|
d.Database = shared.Database{
|
||||||
DB: d.db,
|
DB: d.db,
|
||||||
|
Cache: cache,
|
||||||
Writer: sqlutil.NewExclusiveWriter(),
|
Writer: sqlutil.NewExclusiveWriter(),
|
||||||
EventsTable: d.events,
|
EventsTable: d.events,
|
||||||
EventTypesTable: d.eventTypes,
|
EventTypesTable: d.eventTypes,
|
||||||
|
|
|
||||||
|
|
@ -19,18 +19,19 @@ package storage
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/matrix-org/dendrite/internal/caching"
|
||||||
"github.com/matrix-org/dendrite/internal/config"
|
"github.com/matrix-org/dendrite/internal/config"
|
||||||
"github.com/matrix-org/dendrite/roomserver/storage/postgres"
|
"github.com/matrix-org/dendrite/roomserver/storage/postgres"
|
||||||
"github.com/matrix-org/dendrite/roomserver/storage/sqlite3"
|
"github.com/matrix-org/dendrite/roomserver/storage/sqlite3"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Open opens a database connection.
|
// Open opens a database connection.
|
||||||
func Open(dbProperties *config.DatabaseOptions) (Database, error) {
|
func Open(dbProperties *config.DatabaseOptions, cache caching.RoomServerCaches) (Database, error) {
|
||||||
switch {
|
switch {
|
||||||
case dbProperties.ConnectionString.IsSQLite():
|
case dbProperties.ConnectionString.IsSQLite():
|
||||||
return sqlite3.Open(dbProperties)
|
return sqlite3.Open(dbProperties, cache)
|
||||||
case dbProperties.ConnectionString.IsPostgres():
|
case dbProperties.ConnectionString.IsPostgres():
|
||||||
return postgres.Open(dbProperties)
|
return postgres.Open(dbProperties, cache)
|
||||||
default:
|
default:
|
||||||
return nil, fmt.Errorf("unexpected database type")
|
return nil, fmt.Errorf("unexpected database type")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue