MM-41349: CRT, fix LastUpdated semantics (#19523)

* deadcode: remove UpdateChannelLastViewedAt

* deadcode: remove ThreadStore.(Save(Multiple)|Update|Delete)

* deadcode: followThead in App.MarkChannelAsUnreadFromPost

* document ThreadMembership, Thread structs

* maintain LastUpdated consistently

Whenever we touch a `ThreadMembership` record, we should be setting `LastUpdated` to the current timestamp. The mobile client relies on this to detect changes to these records.

* simplify: never updateThreads from `App.MarkChannelAsUnreadFromPost`

Change all invocations of `ChannelStore.UpdateLastViewedAtPost` from `App.MarkChannelAsUnreadFromPost` to pass `updateThreads` as `false`. When `ChannelStore.UpdateLastViewedAtPost` was invoked with `updateThreads` as `true`, it would in turn call `ThreadStore.UpdateUnreadsByChannel` but pass `updateViewedTimestamp` as `false`. This effectively updated the `LastUpdated` field of the corresponding thread memberships but never touched any of the actual data (such as `LastViewed`).

The overall CRT feature continued to work, because `App.MarkChannelAsUnreadFromPost` directly updates the relevant thread memberships via `ThreadStore.MaintainMembership`.

* deadcode: updateThreads in ChannelStore.UpdateLastViewedAtPost

* simplify: never updateThreads from App.SendNotifications

Change all invocations of `ChannelStore.IncrementMentionCount` from
`App.SendNotifications` to pass `updateThreads` as `false`. When `ChannelStore.IncrementMentionCount` was invoked with `updateThreads` as `true`, it would in turn call `ThreadStore.UpdateUnreadsByChannel` but pass `updateViewedTimestamp` as `false`. This effectively updated the `LastUpdated` field of the corresponding thread memberships but never touched any of the actual data (such as `UnreadMentions`).

The overall CRT feature continued to work, because `App.SendNotifications` directly updates the relevant thread memberships mention counts via `ThreadStore.MaintainMembership`.

* deadcode: updateThreads in ChannelStore.IncrementMentionCount

* fix & rename ThreadStore.UpdateUnreadsByChannel

Rename `ThreadStore.UpdateUnreadsByChannel` to `ThreadStore.UpdateLastViewedByThreadIds`, making it unconditionally set the `LastViewed` for the given threads (as well as `LastUpdated`).

All previous invocations of this method that passed `updateViewedTimestamp` have been previously removed.

* unrelated gofmt -w -s changes to satisfy linter

* always set LastUpdated to model.GetMillis()

* deadcode: ThreadStore.SaveMembership

* fix TestMarkUnreadWithThreads

* GetMasterX
Этот коммит содержится в:
Jesse Hallam
2022-02-28 16:24:34 -04:00
коммит произвёл GitHub
родитель cc900149c6
Коммит 6757edc4e2
20 изменённых файлов: 178 добавлений и 813 удалений

Просмотреть файл

@@ -3,11 +3,24 @@
package model
// Thread tracks the metadata associated with a root post and its reply posts.
//
// Note that Thread metadata does not exist until the first reply to a root post.
type Thread struct {
PostId string `json:"id"`
ChannelId string `json:"channel_id"`
ReplyCount int64 `json:"reply_count"`
LastReplyAt int64 `json:"last_reply_at"`
// PostId is the root post of the thread.
PostId string `json:"id"`
// ChannelId is the channel in which the thread was posted.
ChannelId string `json:"channel_id"`
// ReplyCount is the number of replies to the thread (excluding deleted posts).
ReplyCount int64 `json:"reply_count"`
// LastReplyAt is the timestamp of the most recent post to the thread.
LastReplyAt int64 `json:"last_reply_at"`
// Participants is a list of user ids that have replied to the thread, sorted by the oldest
// to newest. Note that the root post author is not included in this list until they reply.
Participants StringArray `json:"participants"`
}
@@ -62,11 +75,37 @@ func (o *Thread) Etag() string {
return Etag(o.PostId, o.LastReplyAt)
}
// ThreadMembership models the relationship between a user and a thread of posts, with a similar
// data structure as ChannelMembership.
type ThreadMembership struct {
PostId string `json:"post_id"`
UserId string `json:"user_id"`
Following bool `json:"following"`
LastViewed int64 `json:"last_view_at"`
LastUpdated int64 `json:"last_update_at"`
UnreadMentions int64 `json:"unread_mentions"`
// PostId is the root post id of the thread in question.
PostId string `json:"post_id"`
// UserId is the user whose membership in the thread is being tracked.
UserId string `json:"user_id"`
// Following tracks whether the user is following the given thread. This defaults to true
// when a ThreadMembership record is created (a record doesn't exist until the user first
// starts following the thread), but the user can stop following or resume following at
// will.
Following bool `json:"following"`
// LastUpdated is either the creation time of the membership record, or the last time the
// membership record was changed (e.g. started/stopped following, viewed thread, mention
// count change).
//
// This field is used to constrain queries of thread memberships to those updated after
// a given timestamp (e.g. on websocket reconnect). It's also used as the time column for
// deletion decisions during any configured retention policy.
LastUpdated int64 `json:"last_update_at"`
// LastViewed is the last time the user viewed this thread. It is the thread analogue to
// the ChannelMembership's LastViewedAt and is used to decide when there are new replies
// for the user and where the user should start reading.
LastViewed int64 `json:"last_view_at"`
// UnreadMentions is the number of unseen at-mentions for the user in the given thread. It
// is the thread analogue to the ChannelMembership's MentionCount, and is used to highlight
// threads with the mention count.
UnreadMentions int64 `json:"unread_mentions"`
}