Only set currently_active if online

Avoid unneeded presence updates when syncing
This commit is contained in:
S7evinK 2022-03-31 20:39:44 +02:00
parent 2826758c8a
commit 68786e9d14
3 changed files with 26 additions and 5 deletions

View file

@ -124,10 +124,11 @@ func GetPresence(
} }
lastActiveTS := gomatrixserverlib.Timestamp(lastActive) lastActiveTS := gomatrixserverlib.Timestamp(lastActive)
currentlyActive := time.Since(lastActiveTS.Time()).Minutes() < 5
return util.JSONResponse{ return util.JSONResponse{
Code: http.StatusOK, Code: http.StatusOK,
JSON: types.PresenceClientResponse{ JSON: types.PresenceClientResponse{
CurrentlyActive: time.Since(lastActiveTS.Time()).Minutes() < 5, CurrentlyActive: &currentlyActive,
LastActiveAgo: time.Since(lastActiveTS.Time()).Milliseconds(), LastActiveAgo: time.Since(lastActiveTS.Time()).Milliseconds(),
Presence: presence.Header.Get("presence"), Presence: presence.Header.Get("presence"),
StatusMsg: &statusMsg, StatusMsg: &statusMsg,

View file

@ -18,6 +18,7 @@ import (
"context" "context"
"database/sql" "database/sql"
"encoding/json" "encoding/json"
"sync"
"time" "time"
"github.com/matrix-org/dendrite/syncapi/types" "github.com/matrix-org/dendrite/syncapi/types"
@ -26,6 +27,7 @@ import (
type PresenceStreamProvider struct { type PresenceStreamProvider struct {
StreamProvider StreamProvider
cache sync.Map
} }
func (p *PresenceStreamProvider) Setup() { func (p *PresenceStreamProvider) Setup() {
@ -64,6 +66,7 @@ func (p *PresenceStreamProvider) IncrementalSync(
rooms, err := p.DB.AllJoinedUsersInRooms(ctx) rooms, err := p.DB.AllJoinedUsersInRooms(ctx)
if err != nil { if err != nil {
req.Log.WithError(err).Error("unable to query joined users") req.Log.WithError(err).Error("unable to query joined users")
return from
} }
sharedUsers := map[string]bool{ sharedUsers := map[string]bool{
@ -88,11 +91,11 @@ func (p *PresenceStreamProvider) IncrementalSync(
} }
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 {
req.Log.WithError(err).Error("unable to query presence for user") req.Log.WithError(err).Warn("unable to query presence for user")
if err == sql.ErrNoRows { if err == sql.ErrNoRows {
continue continue
} }
return to return from
} }
} }
} }
@ -104,8 +107,24 @@ func (p *PresenceStreamProvider) IncrementalSync(
if !sharedUsers[presence.UserID] { if !sharedUsers[presence.UserID] {
continue continue
} }
pres, ok := p.cache.Load(req.Device.UserID + presence.UserID)
if ok {
// skip already sent presence
prevPresence := pres.(*types.Presence)
currentlyActive := time.Since(prevPresence.LastActiveTS.Time()).Minutes() < 5
samePresence := prevPresence.ClientFields.Presence == presence.ClientFields.Presence &&
prevPresence.ClientFields.StatusMsg == presence.ClientFields.StatusMsg
skip := currentlyActive && samePresence && req.Device.UserID != presence.UserID
if skip {
req.Log.Debugf("Skipping presence, no change (%s)", presence.UserID)
continue
}
}
presence.ClientFields.LastActiveAgo = time.Since(presence.LastActiveTS.Time()).Milliseconds() presence.ClientFields.LastActiveAgo = time.Since(presence.LastActiveTS.Time()).Milliseconds()
presence.ClientFields.CurrentlyActive = time.Since(presence.LastActiveTS.Time()).Minutes() < 5 currentlyActive := time.Since(presence.LastActiveTS.Time()).Minutes() < 5
if presence.ClientFields.Presence == "online" {
presence.ClientFields.CurrentlyActive = &currentlyActive
}
content, err := json.Marshal(presence.ClientFields) content, err := json.Marshal(presence.ClientFields)
if err != nil { if err != nil {
@ -120,6 +139,7 @@ func (p *PresenceStreamProvider) IncrementalSync(
if presence.StreamPos > lastPos { if presence.StreamPos > lastPos {
lastPos = presence.StreamPos lastPos = presence.StreamPos
} }
p.cache.Store(req.Device.UserID+presence.UserID, presence)
} }
return lastPos return lastPos

View file

@ -522,7 +522,7 @@ type Presence struct {
} }
type PresenceClientResponse struct { type PresenceClientResponse struct {
CurrentlyActive bool `json:"currently_active"` CurrentlyActive *bool `json:"currently_active,omitempty"`
LastActiveAgo int64 `json:"last_active_ago,omitempty"` LastActiveAgo int64 `json:"last_active_ago,omitempty"`
Presence string `json:"presence"` Presence string `json:"presence"`
StatusMsg *string `json:"status_msg,omitempty"` StatusMsg *string `json:"status_msg,omitempty"`