MM-36545 Fix replica lag issue causing missed websocket events to update following (#17989)
* Fix replica lag issue causing missed websocket events to update following * Add mutex to prevent data race * Query thread membership if null * Fix style
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
e538604345
Коммит
b01f8ab0c8
@@ -8,6 +8,7 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
|
"sync"
|
||||||
"unicode"
|
"unicode"
|
||||||
"unicode/utf8"
|
"unicode/utf8"
|
||||||
|
|
||||||
@@ -171,6 +172,8 @@ func (a *App) SendNotifications(post *model.Post, team *model.Team, channel *mod
|
|||||||
updateMentionChans := []chan *model.AppError{}
|
updateMentionChans := []chan *model.AppError{}
|
||||||
mentionAutofollowChans := []chan *model.AppError{}
|
mentionAutofollowChans := []chan *model.AppError{}
|
||||||
threadParticipants := map[string]bool{post.UserId: true}
|
threadParticipants := map[string]bool{post.UserId: true}
|
||||||
|
participantMemberships := map[string]*model.ThreadMembership{}
|
||||||
|
membershipsMutex := &sync.Mutex{}
|
||||||
if *a.Config().ServiceSettings.ThreadAutoFollow && post.RootId != "" {
|
if *a.Config().ServiceSettings.ThreadAutoFollow && post.RootId != "" {
|
||||||
var rootMentions *ExplicitMentions
|
var rootMentions *ExplicitMentions
|
||||||
if parentPostList != nil {
|
if parentPostList != nil {
|
||||||
@@ -203,6 +206,9 @@ func (a *App) SendNotifications(post *model.Post, team *model.Team, channel *mod
|
|||||||
}
|
}
|
||||||
|
|
||||||
if membership != nil && !membership.Following {
|
if membership != nil && !membership.Following {
|
||||||
|
membershipsMutex.Lock()
|
||||||
|
participantMemberships[userID] = membership
|
||||||
|
membershipsMutex.Unlock()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -217,11 +223,14 @@ func (a *App) SendNotifications(post *model.Post, team *model.Team, channel *mod
|
|||||||
UpdateViewedTimestamp: userID == post.UserId,
|
UpdateViewedTimestamp: userID == post.UserId,
|
||||||
UpdateParticipants: userID == post.UserId,
|
UpdateParticipants: userID == post.UserId,
|
||||||
}
|
}
|
||||||
_, err := a.Srv().Store.Thread().MaintainMembership(userID, post.RootId, opts)
|
threadMembership, err := a.Srv().Store.Thread().MaintainMembership(userID, post.RootId, opts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
mac <- model.NewAppError("SendNotifications", "app.channel.autofollow.app_error", nil, err.Error(), http.StatusInternalServerError)
|
mac <- model.NewAppError("SendNotifications", "app.channel.autofollow.app_error", nil, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
membershipsMutex.Lock()
|
||||||
|
participantMemberships[userID] = threadMembership
|
||||||
|
membershipsMutex.Unlock()
|
||||||
|
|
||||||
mac <- nil
|
mac <- nil
|
||||||
}(id)
|
}(id)
|
||||||
@@ -469,14 +478,20 @@ func (a *App) SendNotifications(post *model.Post, team *model.Team, channel *mod
|
|||||||
for _, uid := range followers {
|
for _, uid := range followers {
|
||||||
sendEvent := *a.Config().ServiceSettings.CollapsedThreads == model.CollapsedThreadsDefaultOn
|
sendEvent := *a.Config().ServiceSettings.CollapsedThreads == model.CollapsedThreadsDefaultOn
|
||||||
// check if a participant has overridden collapsed threads settings
|
// check if a participant has overridden collapsed threads settings
|
||||||
if preference, err := a.Srv().Store.Preference().Get(uid, model.PreferenceCategoryDisplaySettings, model.PreferenceNameCollapsedThreadsEnabled); err == nil {
|
if preference, prefErr := a.Srv().Store.Preference().Get(uid, model.PreferenceCategoryDisplaySettings, model.PreferenceNameCollapsedThreadsEnabled); prefErr == nil {
|
||||||
sendEvent = preference.Value == "on"
|
sendEvent = preference.Value == "on"
|
||||||
}
|
}
|
||||||
if sendEvent {
|
if sendEvent {
|
||||||
message := model.NewWebSocketEvent(model.WebsocketEventThreadUpdated, team.Id, "", uid, nil)
|
message := model.NewWebSocketEvent(model.WebsocketEventThreadUpdated, team.Id, "", uid, nil)
|
||||||
threadMembership, err := a.Srv().Store.Thread().GetMembershipForUser(uid, post.RootId)
|
threadMembership := participantMemberships[uid]
|
||||||
if err != nil {
|
if threadMembership == nil {
|
||||||
return nil, errors.Wrapf(err, "cannot get thread membership %q for user %q", post.RootId, uid)
|
threadMembership, err = a.Srv().Store.Thread().GetMembershipForUser(uid, post.RootId)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrapf(err, "Missing thread membership for participant in notifications. user_id=%q thread_id=%q", uid, post.RootId)
|
||||||
|
}
|
||||||
|
if threadMembership == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
}
|
}
|
||||||
userThread, err := a.Srv().Store.Thread().GetThreadForUser(channel.TeamId, threadMembership, true)
|
userThread, err := a.Srv().Store.Thread().GetThreadForUser(channel.TeamId, threadMembership, true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
Ссылка в новой задаче
Block a user