Process different rooms in sync responses in goroutines
This commit is contained in:
parent
5ee6aa72db
commit
f668faa894
@ -277,3 +277,11 @@ func (config *Config) LoadRoom(_ id.RoomID) *mautrix.Room {
|
|||||||
func (config *Config) GetRoom(roomID id.RoomID) *rooms.Room {
|
func (config *Config) GetRoom(roomID id.RoomID) *rooms.Room {
|
||||||
return config.Rooms.GetOrCreate(roomID)
|
return config.Rooms.GetOrCreate(roomID)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (config *Config) DisableUnloading() {
|
||||||
|
config.Rooms.DisableUnloading()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (config *Config) EnableUnloading() {
|
||||||
|
config.Rooms.EnableUnloading()
|
||||||
|
}
|
||||||
|
@ -213,13 +213,6 @@ func (room *Room) Unload() bool {
|
|||||||
debug.Print("Unloading", room.ID)
|
debug.Print("Unloading", room.ID)
|
||||||
room.Save()
|
room.Save()
|
||||||
room.state = nil
|
room.state = nil
|
||||||
room.topicCache = ""
|
|
||||||
room.CanonicalAliasCache = ""
|
|
||||||
room.firstMemberCache = nil
|
|
||||||
room.secondMemberCache = nil
|
|
||||||
room.memberCache = nil
|
|
||||||
room.exMemberCache = nil
|
|
||||||
room.replacedByCache = nil
|
|
||||||
if room.postUnload != nil {
|
if room.postUnload != nil {
|
||||||
room.postUnload()
|
room.postUnload()
|
||||||
}
|
}
|
||||||
|
@ -39,6 +39,7 @@ type RoomCache struct {
|
|||||||
maxSize int
|
maxSize int
|
||||||
maxAge int64
|
maxAge int64
|
||||||
getOwner func() id.UserID
|
getOwner func() id.UserID
|
||||||
|
noUnload bool
|
||||||
|
|
||||||
Map map[id.RoomID]*Room
|
Map map[id.RoomID]*Room
|
||||||
head *Room
|
head *Room
|
||||||
@ -58,6 +59,14 @@ func NewRoomCache(listPath, directory string, maxSize int, maxAge int64, getOwne
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (cache *RoomCache) DisableUnloading() {
|
||||||
|
cache.noUnload = true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cache *RoomCache) EnableUnloading() {
|
||||||
|
cache.noUnload = false
|
||||||
|
}
|
||||||
|
|
||||||
func (cache *RoomCache) LoadList() error {
|
func (cache *RoomCache) LoadList() error {
|
||||||
cache.Lock()
|
cache.Lock()
|
||||||
defer cache.Unlock()
|
defer cache.Unlock()
|
||||||
@ -160,6 +169,9 @@ func (cache *RoomCache) Touch(roomID id.RoomID) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (cache *RoomCache) TouchNode(node *Room) {
|
func (cache *RoomCache) TouchNode(node *Room) {
|
||||||
|
if cache.noUnload || node.touch + 2 > time.Now().Unix() {
|
||||||
|
return
|
||||||
|
}
|
||||||
cache.Lock()
|
cache.Lock()
|
||||||
cache.touch(node)
|
cache.touch(node)
|
||||||
cache.Unlock()
|
cache.Unlock()
|
||||||
@ -200,6 +212,7 @@ func (cache *RoomCache) get(roomID id.RoomID) *Room {
|
|||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cache *RoomCache) Put(room *Room) {
|
func (cache *RoomCache) Put(room *Room) {
|
||||||
cache.Lock()
|
cache.Lock()
|
||||||
node := cache.get(room.ID)
|
node := cache.get(room.ID)
|
||||||
@ -283,6 +296,9 @@ func (cache *RoomCache) ForceClean() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (cache *RoomCache) clean(force bool) {
|
func (cache *RoomCache) clean(force bool) {
|
||||||
|
if cache.noUnload && !force {
|
||||||
|
return
|
||||||
|
}
|
||||||
origSize := cache.size
|
origSize := cache.size
|
||||||
maxTS := time.Now().Unix() - cache.maxAge
|
maxTS := time.Now().Unix() - cache.maxAge
|
||||||
for cache.size > cache.maxSize {
|
for cache.size > cache.maxSize {
|
||||||
|
@ -20,6 +20,7 @@ package matrix
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"maunium.net/go/mautrix"
|
"maunium.net/go/mautrix"
|
||||||
@ -33,6 +34,8 @@ import (
|
|||||||
type SyncerSession interface {
|
type SyncerSession interface {
|
||||||
GetRoom(id id.RoomID) *rooms.Room
|
GetRoom(id id.RoomID) *rooms.Room
|
||||||
GetUserID() id.UserID
|
GetUserID() id.UserID
|
||||||
|
DisableUnloading()
|
||||||
|
EnableUnloading()
|
||||||
}
|
}
|
||||||
|
|
||||||
type EventSource int
|
type EventSource int
|
||||||
@ -108,51 +111,80 @@ func NewGomuksSyncer(session SyncerSession) *GomuksSyncer {
|
|||||||
|
|
||||||
// ProcessResponse processes a Matrix sync response.
|
// ProcessResponse processes a Matrix sync response.
|
||||||
func (s *GomuksSyncer) ProcessResponse(res *mautrix.RespSync, since string) (err error) {
|
func (s *GomuksSyncer) ProcessResponse(res *mautrix.RespSync, since string) (err error) {
|
||||||
|
if since == "" {
|
||||||
|
s.Session.DisableUnloading()
|
||||||
|
}
|
||||||
debug.Print("Received sync response")
|
debug.Print("Received sync response")
|
||||||
s.processSyncEvents(nil, res.Presence.Events, EventSourcePresence)
|
s.processSyncEvents(nil, res.Presence.Events, EventSourcePresence)
|
||||||
s.processSyncEvents(nil, res.AccountData.Events, EventSourceAccountData)
|
s.processSyncEvents(nil, res.AccountData.Events, EventSourceAccountData)
|
||||||
|
|
||||||
|
wait := &sync.WaitGroup{}
|
||||||
|
|
||||||
|
wait.Add(len(res.Rooms.Join))
|
||||||
for roomID, roomData := range res.Rooms.Join {
|
for roomID, roomData := range res.Rooms.Join {
|
||||||
room := s.Session.GetRoom(roomID)
|
go s.processJoinedRoom(roomID, roomData, wait)
|
||||||
room.UpdateSummary(roomData.Summary)
|
|
||||||
s.processSyncEvents(room, roomData.State.Events, EventSourceJoin|EventSourceState)
|
|
||||||
s.processSyncEvents(room, roomData.Timeline.Events, EventSourceJoin|EventSourceTimeline)
|
|
||||||
s.processSyncEvents(room, roomData.Ephemeral.Events, EventSourceJoin|EventSourceEphemeral)
|
|
||||||
s.processSyncEvents(room, roomData.AccountData.Events, EventSourceJoin|EventSourceAccountData)
|
|
||||||
|
|
||||||
if len(room.PrevBatch) == 0 {
|
|
||||||
room.PrevBatch = roomData.Timeline.PrevBatch
|
|
||||||
}
|
|
||||||
room.LastPrevBatch = roomData.Timeline.PrevBatch
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wait.Add(len(res.Rooms.Invite))
|
||||||
for roomID, roomData := range res.Rooms.Invite {
|
for roomID, roomData := range res.Rooms.Invite {
|
||||||
room := s.Session.GetRoom(roomID)
|
go s.processInvitedRoom(roomID, roomData, wait)
|
||||||
room.UpdateSummary(roomData.Summary)
|
|
||||||
s.processSyncEvents(room, roomData.State.Events, EventSourceInvite|EventSourceState)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wait.Add(len(res.Rooms.Leave))
|
||||||
for roomID, roomData := range res.Rooms.Leave {
|
for roomID, roomData := range res.Rooms.Leave {
|
||||||
room := s.Session.GetRoom(roomID)
|
go s.processLeftRoom(roomID, roomData, wait)
|
||||||
room.HasLeft = true
|
|
||||||
room.UpdateSummary(roomData.Summary)
|
|
||||||
s.processSyncEvents(room, roomData.State.Events, EventSourceLeave|EventSourceState)
|
|
||||||
s.processSyncEvents(room, roomData.Timeline.Events, EventSourceLeave|EventSourceTimeline)
|
|
||||||
|
|
||||||
if len(room.PrevBatch) == 0 {
|
|
||||||
room.PrevBatch = roomData.Timeline.PrevBatch
|
|
||||||
}
|
|
||||||
room.LastPrevBatch = roomData.Timeline.PrevBatch
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wait.Wait()
|
||||||
|
|
||||||
if since == "" && s.InitDoneCallback != nil {
|
if since == "" && s.InitDoneCallback != nil {
|
||||||
s.InitDoneCallback()
|
s.InitDoneCallback()
|
||||||
|
s.Session.EnableUnloading()
|
||||||
}
|
}
|
||||||
s.FirstSyncDone = true
|
s.FirstSyncDone = true
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *GomuksSyncer) processJoinedRoom(roomID id.RoomID, roomData mautrix.SyncJoinedRoom, wait *sync.WaitGroup) {
|
||||||
|
defer debug.Recover()
|
||||||
|
room := s.Session.GetRoom(roomID)
|
||||||
|
room.UpdateSummary(roomData.Summary)
|
||||||
|
s.processSyncEvents(room, roomData.State.Events, EventSourceJoin|EventSourceState)
|
||||||
|
s.processSyncEvents(room, roomData.Timeline.Events, EventSourceJoin|EventSourceTimeline)
|
||||||
|
s.processSyncEvents(room, roomData.Ephemeral.Events, EventSourceJoin|EventSourceEphemeral)
|
||||||
|
s.processSyncEvents(room, roomData.AccountData.Events, EventSourceJoin|EventSourceAccountData)
|
||||||
|
|
||||||
|
if len(room.PrevBatch) == 0 {
|
||||||
|
room.PrevBatch = roomData.Timeline.PrevBatch
|
||||||
|
}
|
||||||
|
room.LastPrevBatch = roomData.Timeline.PrevBatch
|
||||||
|
wait.Done()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *GomuksSyncer) processInvitedRoom(roomID id.RoomID, roomData mautrix.SyncInvitedRoom, wait *sync.WaitGroup) {
|
||||||
|
defer debug.Recover()
|
||||||
|
room := s.Session.GetRoom(roomID)
|
||||||
|
room.UpdateSummary(roomData.Summary)
|
||||||
|
s.processSyncEvents(room, roomData.State.Events, EventSourceInvite|EventSourceState)
|
||||||
|
wait.Done()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *GomuksSyncer) processLeftRoom(roomID id.RoomID, roomData mautrix.SyncLeftRoom, wait *sync.WaitGroup) {
|
||||||
|
defer debug.Recover()
|
||||||
|
room := s.Session.GetRoom(roomID)
|
||||||
|
room.HasLeft = true
|
||||||
|
room.UpdateSummary(roomData.Summary)
|
||||||
|
s.processSyncEvents(room, roomData.State.Events, EventSourceLeave|EventSourceState)
|
||||||
|
s.processSyncEvents(room, roomData.Timeline.Events, EventSourceLeave|EventSourceTimeline)
|
||||||
|
|
||||||
|
if len(room.PrevBatch) == 0 {
|
||||||
|
room.PrevBatch = roomData.Timeline.PrevBatch
|
||||||
|
}
|
||||||
|
room.LastPrevBatch = roomData.Timeline.PrevBatch
|
||||||
|
wait.Done()
|
||||||
|
}
|
||||||
|
|
||||||
func (s *GomuksSyncer) processSyncEvents(room *rooms.Room, events []*event.Event, source EventSource) {
|
func (s *GomuksSyncer) processSyncEvents(room *rooms.Room, events []*event.Event, source EventSource) {
|
||||||
for _, evt := range events {
|
for _, evt := range events {
|
||||||
s.processSyncEvent(room, evt, source)
|
s.processSyncEvent(room, evt, source)
|
||||||
|
Loading…
Reference in New Issue
Block a user