caches

package
v0.99.16 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 26, 2024 License: Apache-2.0 Imports: 12 Imported by: 0

Documentation

Index

Constants

View Source
const (
	InvitesAreHighlightsValue = 1 // invite -> highlight count = 1
)

Variables

This section is empty.

Functions

This section is empty.

Types

type AccountDataUpdate

type AccountDataUpdate struct {
	AccountData []state.AccountData
}

AccountDataUpdate represents the (global) `account_data` section of a v2 sync response.

func (*AccountDataUpdate) Type added in v0.99.1

func (u *AccountDataUpdate) Type() string

type CacheFinder

type CacheFinder interface {
	CacheForUser(userID string) *UserCache
}

type DeviceDataUpdate added in v0.98.1

type DeviceDataUpdate struct {
}

func (DeviceDataUpdate) Type added in v0.99.1

func (u DeviceDataUpdate) Type() string

type DeviceEventsUpdate added in v0.98.1

type DeviceEventsUpdate struct {
}

func (DeviceEventsUpdate) Type added in v0.99.1

func (u DeviceEventsUpdate) Type() string

type EventData

type EventData struct {
	Event     json.RawMessage
	RoomID    string
	EventType string
	StateKey  *string
	Content   gjson.Result
	Timestamp uint64
	Sender    string
	// TransactionID is the unsigned.transaction_id field in the event as stored in the
	// syncv3_events table, or the empty string if there is no such field.
	//
	// We may see the event on poller A without a transaction_id, and then later on
	// poller B with a transaction_id. If this happens, we make a temporary note of the
	// transaction_id in the syncv3_txns table, but do not edit the persisted event.
	// This means that this field is not authoritative; we only include it here as a
	// hint to avoid unnecessary waits for V2TransactionID payloads.
	TransactionID string

	// the number of joined users in this room. Use this value and don't try to work it out as you
	// may get it wrong due to Synapse sending duplicate join events(!) This value has them de-duped
	// correctly.
	JoinCount   int
	InviteCount int

	// NID is the nid for this event; or a non-nid sentinel value. Current sentinels are
	//  - PosAlwaysProcess and PosDoNotProcess, for things outside the event timeline
	//    e.g invites; and
	//  - `0` used by UserCache.OnRegistered to inject space children events at startup.
	//    It's referenced in ConnState.OnRoomUpdateand UserCache.OnSpaceUpdate
	NID int64

	// Update consumers will usually ignore updates with a NID < what they have seen before for this room.
	// However, in some cases, we want to force the consumer to process this event even though the NID
	// may be < what they have seen before. Currently, we use this to force consumers to process invites
	// for a connected client, as the invite itself has no event NID due to the proxy not being in the room yet.
	AlwaysProcess bool

	// Flag set when this event should force the room contents to be resent e.g
	// state res, initial join, etc
	ForceInitial bool
}

type GlobalCache

type GlobalCache struct {
	// LoadJoinedRoomsOverride allows tests to mock out the behaviour of LoadJoinedRooms.
	LoadJoinedRoomsOverride func(userID string) (pos int64, joinedRooms map[string]*internal.RoomMetadata, joinTimings map[string]internal.EventMetadata, latestNIDs map[string]int64, err error)
	// contains filtered or unexported fields
}

The purpose of global cache is to store global-level information about all rooms the server is aware of. Global-level information is represented as internal.RoomMetadata and includes things like Heroes, join/invite counts, if the room is encrypted, etc. Basically anything that is the same for all users of the system. This information is populated at startup from the database and then kept up-to-date by hooking into the Dispatcher for new events.

func NewGlobalCache

func NewGlobalCache(store *state.Storage) *GlobalCache

func (*GlobalCache) LoadJoinedRooms

func (c *GlobalCache) LoadJoinedRooms(ctx context.Context, userID string) (
	pos int64, joinedRooms map[string]*internal.RoomMetadata, joinTimingByRoomID map[string]internal.EventMetadata,
	latestNIDs map[string]int64, err error,
)

LoadJoinedRooms loads all current joined room metadata for the user given, together with timing info for the user's latest join (excluding profile changes) to the room. Returns the absolute database position (the latest event NID across the whole DB), along with the results.

The two maps returned by this function have exactly the same set of keys. Each is nil iff a non-nil error is returned. TODO: remove with LoadRoomState? FIXME: return args are a mess

func (*GlobalCache) LoadRoomState

func (c *GlobalCache) LoadRoomState(ctx context.Context, roomIDs []string, loadPosition int64, requiredStateMap *internal.RequiredStateMap, roomToUsersInTimeline map[string][]string) map[string][]json.RawMessage

TODO: remove? Doesn't touch global cache fields

func (*GlobalCache) LoadRooms

func (c *GlobalCache) LoadRooms(ctx context.Context, roomIDs ...string) map[string]*internal.RoomMetadata

LoadRooms loads the current room metadata for the given room IDs. Races unless you call this in a dispatcher loop. Always returns copies of the room metadata so ownership can be passed to other threads.

func (*GlobalCache) LoadRoomsFromMap added in v0.99.3

func (c *GlobalCache) LoadRoomsFromMap(ctx context.Context, joinTimingsByRoomID map[string]internal.EventMetadata) map[string]*internal.RoomMetadata

LoadRoomsFromMap is like LoadRooms, except it is given a map with room IDs as keys and returns rooms in a map. The output map is non-nil and contains exactly the same set of keys as the input map. The values in the input map are completely ignored.

func (*GlobalCache) LoadStateEvent

func (c *GlobalCache) LoadStateEvent(ctx context.Context, roomID string, loadPosition int64, evType, stateKey string) json.RawMessage

func (*GlobalCache) OnEphemeralEvent

func (c *GlobalCache) OnEphemeralEvent(ctx context.Context, roomID string, ephEvent json.RawMessage)

func (*GlobalCache) OnInvalidateRoom added in v0.99.11

func (c *GlobalCache) OnInvalidateRoom(ctx context.Context, roomID string)

func (*GlobalCache) OnNewEvent

func (c *GlobalCache) OnNewEvent(
	ctx context.Context, ed *EventData,
)

func (*GlobalCache) OnReceipt added in v0.99.1

func (c *GlobalCache) OnReceipt(ctx context.Context, receipt internal.Receipt)

func (*GlobalCache) OnRegistered

func (c *GlobalCache) OnRegistered(_ context.Context) error

func (*GlobalCache) Startup

func (c *GlobalCache) Startup(roomIDToMetadata map[string]internal.RoomMetadata) error

Startup will populate the cache with the provided metadata. Must be called prior to starting any v2 pollers else this operation can race. Consider:

  • V2 poll loop started early
  • Join event arrives, NID=50
  • PopulateGlobalCache loads the latest NID=50, processes this join event in the process
  • OnNewEvents is called with the join event
  • join event is processed twice.

type InviteData

type InviteData struct {
	InviteState          []json.RawMessage
	Heroes               []internal.Hero
	InviteEvent          *EventData
	NameEvent            string // the content of m.room.name, NOT the calculated name
	AvatarEvent          string // the content of m.room.avatar, NOT the calculated avatar
	CanonicalAlias       string
	LastMessageTimestamp uint64
	Encrypted            bool
	IsDM                 bool
	RoomType             string
	// contains filtered or unexported fields
}

Subset of data from internal.RoomMetadata which we can glean from invite_state. Processed in the same way as joined rooms!

func NewInviteData

func NewInviteData(ctx context.Context, userID, roomID string, inviteState []json.RawMessage) *InviteData

func (*InviteData) RoomMetadata

func (i *InviteData) RoomMetadata() *internal.RoomMetadata

type InviteUpdate

type InviteUpdate struct {
	RoomUpdate
	InviteData InviteData
}

InviteUpdate corresponds to a key-value pair from a v2 sync's `invite` section.

func (*InviteUpdate) Type added in v0.99.1

func (u *InviteUpdate) Type() string

type JoinChecker added in v0.99.15

type JoinChecker interface {
	IsUserJoined(userID, roomID string) bool
}

type ReceiptUpdate

type ReceiptUpdate struct {
	RoomUpdate
	Receipt internal.Receipt
}

RecieptUpdate corresponds to a receipt EDU in the `ephemeral` section of a joined room's v2 sync resposne.

func (*ReceiptUpdate) Type added in v0.99.1

func (u *ReceiptUpdate) Type() string

type RoomAccountDataUpdate

type RoomAccountDataUpdate struct {
	RoomUpdate
	AccountData []state.AccountData
}

RoomAccountDataUpdate represents the `account_data` section of joined room's v2 sync response.

func (*RoomAccountDataUpdate) Type added in v0.99.1

func (u *RoomAccountDataUpdate) Type() string

type RoomEventUpdate

type RoomEventUpdate struct {
	RoomUpdate
	EventData *EventData
}

RoomEventUpdate corresponds to a single event seen in a joined room's timeline under sync v2.

func (*RoomEventUpdate) Type added in v0.99.1

func (u *RoomEventUpdate) Type() string

type RoomUpdate

type RoomUpdate interface {
	Update
	RoomID() string
	GlobalRoomMetadata() *internal.RoomMetadata
	UserRoomMetadata() *UserRoomData
}

type TransactionIDFetcher added in v0.99.0

type TransactionIDFetcher interface {
	TransactionIDForEvents(userID, deviceID string, eventIDs []string) (eventIDToTxnID map[string]string)
}

type TypingUpdate

type TypingUpdate struct {
	RoomUpdate
}

TypingEdu corresponds to a typing EDU in the `ephemeral` section of a joined room's v2 sync resposne.

func (*TypingUpdate) Type added in v0.99.1

func (u *TypingUpdate) Type() string

type UnreadCountUpdate

type UnreadCountUpdate struct {
	RoomUpdate
	HasCountDecreased bool
}

UnreadCountUpdate represents a change in highlight or notification count change. The current counts are determinted from sync v2 responses; the pollers track changes to those counts to determine if they have decreased, remained unchanged, or increased.

func (*UnreadCountUpdate) Type added in v0.99.1

func (u *UnreadCountUpdate) Type() string

type Update

type Update interface {
	Type() string
}

type UserCache

type UserCache struct {
	LazyLoadTimelinesOverride func(loadPos int64, roomIDs []string, maxTimelineEvents int) map[string]state.LatestEvents
	UserID                    string
	// contains filtered or unexported fields
}

Tracks data specific to a given user. Specifically, this is the map of room ID to UserRoomData. This data is user-scoped, not global or connection scoped.

func NewUserCache

func NewUserCache(userID string, globalCache *GlobalCache, store UserCacheStore, txnIDs TransactionIDFetcher, joinChecker JoinChecker) *UserCache

func (*UserCache) AnnotateWithTransactionIDs

func (c *UserCache) AnnotateWithTransactionIDs(ctx context.Context, userID string, deviceID string, roomIDToEvents map[string][]json.RawMessage) map[string][]json.RawMessage

AnnotateWithTransactionIDs should be called just prior to returning events to the client. This will modify the events to insert the correct transaction IDs if needed. This is required because events are globally scoped, so if Alice sends a message, Bob might receive it first on his v2 loop which would cause the transaction ID to be missing from the event. Instead, we always look for txn IDs in the v2 poller, and then set them appropriately at request time.

func (*UserCache) AttemptToFetchPrevBatch added in v0.99.13

func (c *UserCache) AttemptToFetchPrevBatch(ctx context.Context, roomID string, firstTimelineEvent *EventData) (prevBatch string)

AttemptToFetchPrevBatch tries to find a prev_batch value for the given event. This may not always succeed.

func (*UserCache) Invites

func (c *UserCache) Invites() map[string]UserRoomData

func (*UserCache) LazyLoadTimelines

func (c *UserCache) LazyLoadTimelines(ctx context.Context, loadPos int64, roomIDs []string, maxTimelineEvents int) map[string]state.LatestEvents

LazyLoadTimelines loads the most recent timeline events (up to `maxTimelineEvents`) for each of the given rooms from the database (plus other timeline-related data). Only events with NID <= loadPos are returned. Events from senders ignored by this user are dropped. Returns nil on error.

func (*UserCache) LoadRoomData

func (c *UserCache) LoadRoomData(roomID string) UserRoomData

func (*UserCache) LoadRooms added in v0.99.11

func (c *UserCache) LoadRooms(roomIDs ...string) map[string]UserRoomData

LoadRooms is a batch version of LoadRoomData. Returns a map keyed by roomID.

func (*UserCache) OnAccountData

func (c *UserCache) OnAccountData(ctx context.Context, datas []state.AccountData)

func (*UserCache) OnEphemeralEvent

func (c *UserCache) OnEphemeralEvent(ctx context.Context, roomID string, ephEvent json.RawMessage)

func (*UserCache) OnInvite

func (c *UserCache) OnInvite(ctx context.Context, roomID string, inviteStateEvents []json.RawMessage)

func (*UserCache) OnLeftRoom

func (c *UserCache) OnLeftRoom(ctx context.Context, roomID string, leaveEvent json.RawMessage)

func (*UserCache) OnNewEvent

func (c *UserCache) OnNewEvent(ctx context.Context, eventData *EventData)

func (*UserCache) OnReceipt added in v0.99.1

func (c *UserCache) OnReceipt(ctx context.Context, receipt internal.Receipt)

func (*UserCache) OnRegistered

func (c *UserCache) OnRegistered(ctx context.Context) error

OnRegistered is called after the sync3.Dispatcher has successfully registered this cache to receive updates. We use this to run some final initialisation logic that is sensitive to race conditions; confusingly, most of the initialisation is driven externally by sync3.SyncLiveHandler.userCaches. It's important that we don't spend too long inside this function, because it is called within a global lock on the sync3.Dispatcher (see sync3.Dispatcher.Register).

func (*UserCache) OnSpaceUpdate

func (c *UserCache) OnSpaceUpdate(ctx context.Context, parentRoomID, childRoomID string, isDeleted bool, eventData *EventData)

func (*UserCache) OnUnreadCounts

func (c *UserCache) OnUnreadCounts(ctx context.Context, roomID string, highlightCount, notifCount *int)

func (*UserCache) ShouldIgnore added in v0.99.6

func (u *UserCache) ShouldIgnore(userID string) bool

func (*UserCache) Subsribe

func (c *UserCache) Subsribe(ucl UserCacheListener) (id int)

func (*UserCache) Unsubscribe

func (c *UserCache) Unsubscribe(id int)

type UserCacheListener

type UserCacheListener interface {
	// Called when there is an update affecting a room e.g new event, unread count update, room account data.
	// Type-cast to find out what the update is about.
	OnRoomUpdate(ctx context.Context, up RoomUpdate)
	// Called when there is an update affecting this user but not in the room e.g global account data, presence.
	// Type-cast to find out what the update is about.
	OnUpdate(ctx context.Context, up Update)
}

type UserCacheStore added in v0.99.13

type UserCacheStore interface {
	LatestEventsInRooms(userID string, roomIDs []string, to int64, limit int) (map[string]*state.LatestEvents, error)
	GetClosestPrevBatch(roomID string, eventNID int64) (prevBatch string)
}

Subset of store functions used by the user cache

type UserRoomData

type UserRoomData struct {
	IsDM              bool
	IsInvite          bool
	HasLeft           bool
	NotificationCount int
	HighlightCount    int
	Invite            *InviteData

	// TODO: should CanonicalisedName really be in RoomConMetadata? It's only set in SetRoom AFAICS
	CanonicalisedName string // stripped leading symbols like #, all in lower case

	// ResolvedAvatarURL is the avatar that should be displayed to this user to
	// represent this room. The empty string means that this room has no avatar.
	// Avatars set in m.room.avatar take precedence; if this is missing and the room is
	// a DM with one other user joined or invited, we fall back to that user's
	// avatar (if any) as specified in their membership event in that room.
	ResolvedAvatarURL string

	// Spaces is the set of room IDs of spaces that this room is part of.
	Spaces map[string]struct{}
	// Map of tag to order float.
	// See https://spec.matrix.org/latest/client-server-api/#room-tagging
	Tags map[string]float64
	// JoinTiming tracks our latest join to the room, excluding profile changes.
	JoinTiming internal.EventMetadata
}

UserRoomData describes a single room from the perspective of particular user. It is primarily used in two places:

  • in the caches.UserCache, to hold the latest version of user-specific data; and
  • in the sync3.RoomConnMetadata struct, to hold the version of data last seen by a given sync connection.

Roughly speaking, the sync3.RoomConnMetadata is constantly catching up with changes in the caches.UserCache.

func NewUserRoomData

func NewUserRoomData() UserRoomData

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL