From 2cebe3b5dc0a17f46cb5e4122a16ed73e9e90d97 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Sun, 10 May 2020 02:28:32 +0300 Subject: [PATCH] Move loaded history pointer to message view When it was in the history manager, it wouldn't get unloaded when the room was unloaded. Hopefully fixes #136 --- interface/matrix.go | 2 +- matrix/history.go | 35 ++++++++++++++++++----------------- matrix/matrix.go | 19 ++++++++++--------- ui/message-view.go | 2 ++ ui/view-main.go | 4 +++- 5 files changed, 34 insertions(+), 28 deletions(-) diff --git a/interface/matrix.go b/interface/matrix.go index 122757f..15bd733 100644 --- a/interface/matrix.go +++ b/interface/matrix.go @@ -55,7 +55,7 @@ type MatrixContainer interface { CreateRoom(req *mautrix.ReqCreateRoom) (*rooms.Room, error) FetchMembers(room *rooms.Room) error - GetHistory(room *rooms.Room, limit int) ([]*muksevt.Event, error) + GetHistory(room *rooms.Room, limit int, dbPointer uint64) ([]*muksevt.Event, uint64, error) GetEvent(room *rooms.Room, eventID id.EventID) (*muksevt.Event, error) GetRoom(roomID id.RoomID) *rooms.Room GetOrCreateRoom(roomID id.RoomID) *rooms.Room diff --git a/matrix/history.go b/matrix/history.go index 4f1cba9..b1e5842 100644 --- a/matrix/history.go +++ b/matrix/history.go @@ -26,10 +26,11 @@ import ( sync "github.com/sasha-s/go-deadlock" bolt "go.etcd.io/bbolt" - "maunium.net/go/gomuks/matrix/muksevt" - "maunium.net/go/gomuks/matrix/rooms" "maunium.net/go/mautrix/event" "maunium.net/go/mautrix/id" + + "maunium.net/go/gomuks/matrix/muksevt" + "maunium.net/go/gomuks/matrix/rooms" ) type HistoryManager struct { @@ -37,8 +38,7 @@ type HistoryManager struct { db *bolt.DB - historyEndPtr map[*rooms.Room]uint64 - historyLoadPtr map[*rooms.Room]uint64 + historyEndPtr map[*rooms.Room]uint64 } var bucketRoomStreams = []byte("room_streams") @@ -49,8 +49,7 @@ const halfUint64 = ^uint64(0) >> 1 func NewHistoryManager(dbPath string) (*HistoryManager, error) { hm := &HistoryManager{ - historyEndPtr: make(map[*rooms.Room]uint64), - historyLoadPtr: make(map[*rooms.Room]uint64), + historyEndPtr: make(map[*rooms.Room]uint64), } db, err := bolt.Open(dbPath, 0600, &bolt.Options{ Timeout: 1, @@ -142,18 +141,19 @@ func (hm *HistoryManager) Update(room *rooms.Room, eventID id.EventID, update fu } func (hm *HistoryManager) Append(room *rooms.Room, events []*event.Event) ([]*muksevt.Event, error) { - return hm.store(room, events, true) + muksEvts, _, err := hm.store(room, events, true) + return muksEvts, err } -func (hm *HistoryManager) Prepend(room *rooms.Room, events []*event.Event) ([]*muksevt.Event, error) { +func (hm *HistoryManager) Prepend(room *rooms.Room, events []*event.Event) ([]*muksevt.Event, uint64, error) { return hm.store(room, events, false) } -func (hm *HistoryManager) store(room *rooms.Room, events []*event.Event, append bool) ([]*muksevt.Event, error) { +func (hm *HistoryManager) store(room *rooms.Room, events []*event.Event, append bool) (newEvents []*muksevt.Event, newPtrStart uint64, err error) { hm.Lock() defer hm.Unlock() - newEvents := make([]*muksevt.Event, len(events)) - err := hm.db.Update(func(tx *bolt.Tx) error { + newEvents = make([]*muksevt.Event, len(events)) + err = hm.db.Update(func(tx *bolt.Tx) error { streamPointers := tx.Bucket(bucketStreamPointers) rid := []byte(room.ID) stream, err := tx.Bucket(bucketRoomStreams).CreateBucketIfNotExists(rid) @@ -205,6 +205,8 @@ func (hm *HistoryManager) store(room *rooms.Room, events []*event.Event, append } } hm.historyEndPtr[room] = ptrStart + eventCount + // TODO this is not the correct value for newPtrStart, figure out what the f*ck is going on here + newPtrStart = ptrStart + eventCount err := streamPointers.Put(rid, itob(ptrStart+eventCount)) if err != nil { return err @@ -213,10 +215,10 @@ func (hm *HistoryManager) store(room *rooms.Room, events []*event.Event, append return nil }) - return newEvents, err + return } -func (hm *HistoryManager) Load(room *rooms.Room, num int) (events []*muksevt.Event, err error) { +func (hm *HistoryManager) Load(room *rooms.Room, num int, ptrStart uint64) (events []*muksevt.Event, newPtrStart uint64, err error) { hm.Lock() defer hm.Unlock() err = hm.db.View(func(tx *bolt.Tx) error { @@ -224,8 +226,7 @@ func (hm *HistoryManager) Load(room *rooms.Room, num int) (events []*muksevt.Eve if stream == nil { return nil } - ptrStart, ok := hm.historyLoadPtr[room] - if !ok { + if ptrStart == 0 { ptrStart = stream.Sequence() + 1 } c := stream.Cursor() @@ -234,7 +235,7 @@ func (hm *HistoryManager) Load(room *rooms.Room, num int) (events []*muksevt.Eve if k == nil || ptrStartFound >= ptrStart { return nil } - hm.historyLoadPtr[room] = ptrStartFound - 1 + newPtrStart = ptrStartFound for ; k != nil && btoi(k) < ptrStart; k, v = c.Next() { evt, parseError := unmarshalEvent(v) if parseError != nil { @@ -268,7 +269,7 @@ func btoi(b []byte) uint64 { func stripRaw(evt *muksevt.Event) { evtCopy := *evt.Event evtCopy.Content = event.Content{ - Parsed: evt.Content.Parsed, + Parsed: evt.Content.Parsed, } evt.Event = &evtCopy } diff --git a/matrix/matrix.go b/matrix/matrix.go index e2e182e..bff9bd2 100644 --- a/matrix/matrix.go +++ b/matrix/matrix.go @@ -966,18 +966,18 @@ func (c *Container) FetchMembers(room *rooms.Room) error { } // GetHistory fetches room history. -func (c *Container) GetHistory(room *rooms.Room, limit int) ([]*muksevt.Event, error) { - events, err := c.history.Load(room, limit) +func (c *Container) GetHistory(room *rooms.Room, limit int, dbPointer uint64) ([]*muksevt.Event, uint64, error) { + events, newDBPointer, err := c.history.Load(room, limit, dbPointer) if err != nil { - return nil, err + return nil, dbPointer, err } if len(events) > 0 { debug.Printf("Loaded %d events for %s from local cache", len(events), room.ID) - return events, nil + return events, newDBPointer, nil } resp, err := c.client.Messages(room.ID, room.PrevBatch, "", 'b', limit) if err != nil { - return nil, err + return nil, dbPointer, err } debug.Printf("Loaded %d events for %s from server from %s to %s", len(resp.Chunk), room.ID, resp.Start, resp.End) for i, evt := range resp.Chunk { @@ -1002,13 +1002,14 @@ func (c *Container) GetHistory(room *rooms.Room, limit int) ([]*muksevt.Event, e room.PrevBatch = resp.End c.config.Rooms.Put(room) if len(resp.Chunk) == 0 { - return []*muksevt.Event{}, nil + return []*muksevt.Event{}, dbPointer, nil } - events, err = c.history.Prepend(room, resp.Chunk) + // TODO newDBPointer isn't accurate in this case yet, fix later + events, newDBPointer, err = c.history.Prepend(room, resp.Chunk) if err != nil { - return nil, err + return nil, dbPointer, err } - return events, nil + return events, dbPointer, nil } func (c *Container) GetEvent(room *rooms.Room, eventID id.EventID) (*muksevt.Event, error) { diff --git a/ui/message-view.go b/ui/message-view.go index 596b9b0..2410cd5 100644 --- a/ui/message-view.go +++ b/ui/message-view.go @@ -51,6 +51,7 @@ type MessageView struct { // Used for locking loadingMessages int32 + historyLoadPtr uint64 _widestSender uint32 _prevWidestSender uint32 @@ -109,6 +110,7 @@ func (view *MessageView) Unload() { view.ScrollOffset = 0 view._widestSender = 5 view.prevMsgCount = -1 + view.historyLoadPtr = 0 view.messagesLock.Unlock() view.msgBufferLock.Unlock() view.messageIDLock.Unlock() diff --git a/ui/view-main.go b/ui/view-main.go index af99b29..0f6098c 100644 --- a/ui/view-main.go +++ b/ui/view-main.go @@ -461,13 +461,15 @@ func (view *MainView) LoadHistory(roomID id.RoomID) { // Update the "Loading more messages..." text view.parent.Render() - history, err := view.matrix.GetHistory(roomView.Room, 50) + history, newLoadPtr, err := view.matrix.GetHistory(roomView.Room, 50, msgView.historyLoadPtr) if err != nil { roomView.AddServiceMessage("Failed to fetch history") debug.Print("Failed to fetch history for", roomView.Room.ID, err) view.parent.Render() return } + //debug.Printf("Load pointer %d -> %d", msgView.historyLoadPtr, newLoadPtr) + msgView.historyLoadPtr = newLoadPtr for _, evt := range history { roomView.AddHistoryEvent(evt) }