mirror of
https://github.com/matrix-org/dendrite.git
synced 2026-01-03 12:13:09 -06:00
Maybe placate the tests
This commit is contained in:
parent
86876781e7
commit
9d34f9738c
|
|
@ -161,5 +161,5 @@ type Presence interface {
|
||||||
GetPresence(ctx context.Context, userID string) (*types.PresenceInternal, error)
|
GetPresence(ctx context.Context, userID string) (*types.PresenceInternal, error)
|
||||||
PresenceAfter(ctx context.Context, after types.StreamPosition) (map[string]*types.PresenceInternal, error)
|
PresenceAfter(ctx context.Context, after types.StreamPosition) (map[string]*types.PresenceInternal, error)
|
||||||
MaxStreamPositionForPresence(ctx context.Context) (types.StreamPosition, error)
|
MaxStreamPositionForPresence(ctx context.Context) (types.StreamPosition, error)
|
||||||
RecentPresence(ctx context.Context) (map[string]*types.PresenceInternal, error)
|
RecentPresence(ctx context.Context) (map[string]*types.PresenceInternal, types.StreamPosition, error)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -172,7 +172,7 @@ func (p *presenceStatements) GetPresenceAfter(
|
||||||
// GetRecentPresence gets updates from the last five minutes.
|
// GetRecentPresence gets updates from the last five minutes.
|
||||||
func (p *presenceStatements) GetRecentPresence(
|
func (p *presenceStatements) GetRecentPresence(
|
||||||
ctx context.Context, txn *sql.Tx,
|
ctx context.Context, txn *sql.Tx,
|
||||||
) (presences map[string]*types.PresenceInternal, err error) {
|
) (presences map[string]*types.PresenceInternal, latest types.StreamPosition, err error) {
|
||||||
presences = make(map[string]*types.PresenceInternal)
|
presences = make(map[string]*types.PresenceInternal)
|
||||||
stmt := sqlutil.TxStmt(txn, p.selectRecentPresenceStmt)
|
stmt := sqlutil.TxStmt(txn, p.selectRecentPresenceStmt)
|
||||||
|
|
||||||
|
|
@ -180,16 +180,19 @@ func (p *presenceStatements) GetRecentPresence(
|
||||||
|
|
||||||
rows, err := stmt.QueryContext(ctx, sinceTS)
|
rows, err := stmt.QueryContext(ctx, sinceTS)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, 0, err
|
||||||
}
|
}
|
||||||
defer internal.CloseAndLogIfError(ctx, rows, "GetPresenceAfter: failed to close rows")
|
defer internal.CloseAndLogIfError(ctx, rows, "GetRecentPresence: failed to close rows")
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
qryRes := &types.PresenceInternal{}
|
qryRes := &types.PresenceInternal{}
|
||||||
if err := rows.Scan(&qryRes.StreamPos, &qryRes.UserID, &qryRes.Presence, &qryRes.ClientFields.StatusMsg, &qryRes.LastActiveTS); err != nil {
|
if err := rows.Scan(&qryRes.StreamPos, &qryRes.UserID, &qryRes.Presence, &qryRes.ClientFields.StatusMsg, &qryRes.LastActiveTS); err != nil {
|
||||||
return nil, err
|
return nil, 0, err
|
||||||
}
|
}
|
||||||
qryRes.ClientFields.Presence = qryRes.Presence.String()
|
qryRes.ClientFields.Presence = qryRes.Presence.String()
|
||||||
presences[qryRes.UserID] = qryRes
|
presences[qryRes.UserID] = qryRes
|
||||||
|
if qryRes.StreamPos > latest {
|
||||||
|
latest = qryRes.StreamPos
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return presences, rows.Err()
|
return presences, latest, rows.Err()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1060,7 +1060,7 @@ func (s *Database) PresenceAfter(ctx context.Context, after types.StreamPosition
|
||||||
return s.Presence.GetPresenceAfter(ctx, nil, after)
|
return s.Presence.GetPresenceAfter(ctx, nil, after)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Database) RecentPresence(ctx context.Context) (map[string]*types.PresenceInternal, error) {
|
func (s *Database) RecentPresence(ctx context.Context) (map[string]*types.PresenceInternal, types.StreamPosition, error) {
|
||||||
return s.Presence.GetRecentPresence(ctx, nil)
|
return s.Presence.GetRecentPresence(ctx, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -187,7 +187,7 @@ func (p *presenceStatements) GetPresenceAfter(
|
||||||
// GetRecentPresence gets updates from the last five minutes.
|
// GetRecentPresence gets updates from the last five minutes.
|
||||||
func (p *presenceStatements) GetRecentPresence(
|
func (p *presenceStatements) GetRecentPresence(
|
||||||
ctx context.Context, txn *sql.Tx,
|
ctx context.Context, txn *sql.Tx,
|
||||||
) (presences map[string]*types.PresenceInternal, err error) {
|
) (presences map[string]*types.PresenceInternal, latest types.StreamPosition, err error) {
|
||||||
presences = make(map[string]*types.PresenceInternal)
|
presences = make(map[string]*types.PresenceInternal)
|
||||||
stmt := sqlutil.TxStmt(txn, p.selectRecentPresenceStmt)
|
stmt := sqlutil.TxStmt(txn, p.selectRecentPresenceStmt)
|
||||||
|
|
||||||
|
|
@ -195,16 +195,19 @@ func (p *presenceStatements) GetRecentPresence(
|
||||||
|
|
||||||
rows, err := stmt.QueryContext(ctx, sinceTS)
|
rows, err := stmt.QueryContext(ctx, sinceTS)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, 0, err
|
||||||
}
|
}
|
||||||
defer internal.CloseAndLogIfError(ctx, rows, "GetPresenceAfter: failed to close rows")
|
defer internal.CloseAndLogIfError(ctx, rows, "GetRecentPresence: failed to close rows")
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
qryRes := &types.PresenceInternal{}
|
qryRes := &types.PresenceInternal{}
|
||||||
if err := rows.Scan(&qryRes.StreamPos, &qryRes.UserID, &qryRes.Presence, &qryRes.ClientFields.StatusMsg, &qryRes.LastActiveTS); err != nil {
|
if err := rows.Scan(&qryRes.StreamPos, &qryRes.UserID, &qryRes.Presence, &qryRes.ClientFields.StatusMsg, &qryRes.LastActiveTS); err != nil {
|
||||||
return nil, err
|
return nil, 0, err
|
||||||
}
|
}
|
||||||
qryRes.ClientFields.Presence = qryRes.Presence.String()
|
qryRes.ClientFields.Presence = qryRes.Presence.String()
|
||||||
presences[qryRes.UserID] = qryRes
|
presences[qryRes.UserID] = qryRes
|
||||||
|
if qryRes.StreamPos > latest {
|
||||||
|
latest = qryRes.StreamPos
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return presences, rows.Err()
|
return presences, latest, rows.Err()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -189,5 +189,5 @@ type Presence interface {
|
||||||
GetPresenceForUser(ctx context.Context, txn *sql.Tx, userID string) (presence *types.PresenceInternal, err error)
|
GetPresenceForUser(ctx context.Context, txn *sql.Tx, userID string) (presence *types.PresenceInternal, err error)
|
||||||
GetMaxPresenceID(ctx context.Context, txn *sql.Tx) (pos types.StreamPosition, err error)
|
GetMaxPresenceID(ctx context.Context, txn *sql.Tx) (pos types.StreamPosition, err error)
|
||||||
GetPresenceAfter(ctx context.Context, txn *sql.Tx, after types.StreamPosition) (presences map[string]*types.PresenceInternal, err error)
|
GetPresenceAfter(ctx context.Context, txn *sql.Tx, after types.StreamPosition) (presences map[string]*types.PresenceInternal, err error)
|
||||||
GetRecentPresence(ctx context.Context, txn *sql.Tx) (presences map[string]*types.PresenceInternal, err error)
|
GetRecentPresence(ctx context.Context, txn *sql.Tx) (presences map[string]*types.PresenceInternal, latest types.StreamPosition, err error)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"database/sql"
|
"database/sql"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"github.com/matrix-org/dendrite/syncapi/notifier"
|
"github.com/matrix-org/dendrite/syncapi/notifier"
|
||||||
|
|
@ -46,44 +47,18 @@ func (p *PresenceStreamProvider) CompleteSync(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
req *types.SyncRequest,
|
req *types.SyncRequest,
|
||||||
) types.StreamPosition {
|
) types.StreamPosition {
|
||||||
presences, err := p.DB.RecentPresence(ctx)
|
presences, latest, err := p.DB.RecentPresence(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
req.Log.WithError(err).Error("p.DB.RecentPresence failed")
|
req.Log.WithError(err).Error("p.DB.RecentPresence failed")
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
if len(presences) == 0 {
|
||||||
for i := range presences {
|
return latest
|
||||||
presence := presences[i]
|
|
||||||
// Ignore users we don't share a room with
|
|
||||||
if req.Device.UserID != presence.UserID && !p.notifier.IsSharedUser(req.Device.UserID, presence.UserID) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
cacheKey := req.Device.UserID + req.Device.ID + presence.UserID
|
|
||||||
|
|
||||||
if _, known := types.PresenceFromString(presence.ClientFields.Presence); known {
|
|
||||||
presence.ClientFields.LastActiveAgo = presence.LastActiveAgo()
|
|
||||||
if presence.ClientFields.Presence == "online" {
|
|
||||||
currentlyActive := presence.CurrentlyActive()
|
|
||||||
presence.ClientFields.CurrentlyActive = ¤tlyActive
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
presence.ClientFields.Presence = "offline"
|
|
||||||
}
|
|
||||||
|
|
||||||
content, err := json.Marshal(presence.ClientFields)
|
|
||||||
if err != nil {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
req.Response.Presence.Events = append(req.Response.Presence.Events, gomatrixserverlib.ClientEvent{
|
|
||||||
Content: content,
|
|
||||||
Sender: presence.UserID,
|
|
||||||
Type: gomatrixserverlib.MPresence,
|
|
||||||
})
|
|
||||||
p.cache.Store(cacheKey, presence)
|
|
||||||
}
|
}
|
||||||
|
if err := p.populatePresence(ctx, req, presences, true); err != nil {
|
||||||
return p.LatestPosition(ctx)
|
return 0
|
||||||
|
}
|
||||||
|
return latest
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *PresenceStreamProvider) IncrementalSync(
|
func (p *PresenceStreamProvider) IncrementalSync(
|
||||||
|
|
@ -96,19 +71,28 @@ func (p *PresenceStreamProvider) IncrementalSync(
|
||||||
req.Log.WithError(err).Error("p.DB.PresenceAfter failed")
|
req.Log.WithError(err).Error("p.DB.PresenceAfter failed")
|
||||||
return from
|
return from
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(presences) == 0 {
|
if len(presences) == 0 {
|
||||||
return to
|
return to
|
||||||
}
|
}
|
||||||
|
if err := p.populatePresence(ctx, req, presences, false); err != nil {
|
||||||
|
return from
|
||||||
|
}
|
||||||
|
return to
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *PresenceStreamProvider) populatePresence(
|
||||||
|
ctx context.Context,
|
||||||
|
req *types.SyncRequest,
|
||||||
|
presences map[string]*types.PresenceInternal,
|
||||||
|
ignoreCache bool,
|
||||||
|
) error {
|
||||||
// add newly joined rooms user presences
|
// add newly joined rooms user presences
|
||||||
newlyJoined := joinedRooms(req.Response, req.Device.UserID)
|
newlyJoined := joinedRooms(req.Response, req.Device.UserID)
|
||||||
if len(newlyJoined) > 0 {
|
if len(newlyJoined) > 0 {
|
||||||
// TODO: This refreshes all lists and is quite expensive
|
// TODO: This refreshes all lists and is quite expensive
|
||||||
// The notifier should update the lists itself
|
// The notifier should update the lists itself
|
||||||
if err = p.notifier.Load(ctx, p.DB); err != nil {
|
if err := p.notifier.Load(ctx, p.DB); err != nil {
|
||||||
req.Log.WithError(err).Error("unable to refresh notifier lists")
|
return err
|
||||||
return from
|
|
||||||
}
|
}
|
||||||
for _, roomID := range newlyJoined {
|
for _, roomID := range newlyJoined {
|
||||||
roomUsers := p.notifier.JoinedUsers(roomID)
|
roomUsers := p.notifier.JoinedUsers(roomID)
|
||||||
|
|
@ -117,19 +101,18 @@ func (p *PresenceStreamProvider) IncrementalSync(
|
||||||
if _, ok := presences[roomUsers[i]]; ok {
|
if _, ok := presences[roomUsers[i]]; ok {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
var err error
|
||||||
presences[roomUsers[i]], err = p.DB.GetPresence(ctx, roomUsers[i])
|
presences[roomUsers[i]], err = p.DB.GetPresence(ctx, roomUsers[i])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if err == sql.ErrNoRows {
|
if err == sql.ErrNoRows {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
req.Log.WithError(err).Error("unable to query presence for user")
|
return err
|
||||||
return from
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
lastPos := to
|
|
||||||
for i := range presences {
|
for i := range presences {
|
||||||
presence := presences[i]
|
presence := presences[i]
|
||||||
// Ignore users we don't share a room with
|
// Ignore users we don't share a room with
|
||||||
|
|
@ -137,15 +120,15 @@ func (p *PresenceStreamProvider) IncrementalSync(
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
cacheKey := req.Device.UserID + req.Device.ID + presence.UserID
|
cacheKey := req.Device.UserID + req.Device.ID + presence.UserID
|
||||||
pres, ok := p.cache.Load(cacheKey)
|
if !ignoreCache {
|
||||||
if ok {
|
pres, ok := p.cache.Load(cacheKey)
|
||||||
// skip already sent presence
|
if ok {
|
||||||
prevPresence := pres.(*types.PresenceInternal)
|
// skip already sent presence
|
||||||
currentlyActive := prevPresence.CurrentlyActive()
|
prevPresence := pres.(*types.PresenceInternal)
|
||||||
skip := prevPresence.Equals(presence) && currentlyActive && req.Device.UserID != presence.UserID
|
currentlyActive := prevPresence.CurrentlyActive()
|
||||||
if skip {
|
if prevPresence.Equals(presence) && currentlyActive && req.Device.UserID != presence.UserID {
|
||||||
req.Log.Debugf("Skipping presence, no change (%s)", presence.UserID)
|
continue
|
||||||
continue
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -161,7 +144,7 @@ func (p *PresenceStreamProvider) IncrementalSync(
|
||||||
|
|
||||||
content, err := json.Marshal(presence.ClientFields)
|
content, err := json.Marshal(presence.ClientFields)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return from
|
return fmt.Errorf("json.Unmarshal: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
req.Response.Presence.Events = append(req.Response.Presence.Events, gomatrixserverlib.ClientEvent{
|
req.Response.Presence.Events = append(req.Response.Presence.Events, gomatrixserverlib.ClientEvent{
|
||||||
|
|
@ -169,13 +152,10 @@ func (p *PresenceStreamProvider) IncrementalSync(
|
||||||
Sender: presence.UserID,
|
Sender: presence.UserID,
|
||||||
Type: gomatrixserverlib.MPresence,
|
Type: gomatrixserverlib.MPresence,
|
||||||
})
|
})
|
||||||
if presence.StreamPos > lastPos {
|
|
||||||
lastPos = presence.StreamPos
|
|
||||||
}
|
|
||||||
p.cache.Store(cacheKey, presence)
|
p.cache.Store(cacheKey, presence)
|
||||||
}
|
}
|
||||||
|
|
||||||
return lastPos
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func joinedRooms(res *types.Response, userID string) []string {
|
func joinedRooms(res *types.Response, userID string) []string {
|
||||||
|
|
|
||||||
|
|
@ -34,8 +34,8 @@ func (d dummyDB) PresenceAfter(ctx context.Context, after types.StreamPosition)
|
||||||
return map[string]*types.PresenceInternal{}, nil
|
return map[string]*types.PresenceInternal{}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d dummyDB) RecentPresence(ctx context.Context) (map[string]*types.PresenceInternal, error) {
|
func (d dummyDB) RecentPresence(ctx context.Context) (map[string]*types.PresenceInternal, types.StreamPosition, error) {
|
||||||
return map[string]*types.PresenceInternal{}, nil
|
return map[string]*types.PresenceInternal{}, 0, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d dummyDB) MaxStreamPositionForPresence(ctx context.Context) (types.StreamPosition, error) {
|
func (d dummyDB) MaxStreamPositionForPresence(ctx context.Context) (types.StreamPosition, error) {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue