[MM-58355] Send invalidate cache message across the cluster so that websocket connections on other instances are invalidated correctly (#27204)
* [MM-58355] Send invalidate cache message across the cluster so that websocket connections on other instances are invalidated correctly * Add suggestion to clear the session cache on the local node as well * Force read from master DB when gettting channel members for websocket to avoid any DB sync issues * PR feedback * Missed generated files
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
91741a7fa4
Коммит
f3e760008c
@@ -82,7 +82,7 @@ func (a *App) SessionHasPermissionToChannel(c request.CTX, session model.Session
|
||||
return false
|
||||
}
|
||||
|
||||
ids, err := a.Srv().Store().Channel().GetAllChannelMembersForUser(session.UserId, true, true)
|
||||
ids, err := a.Srv().Store().Channel().GetAllChannelMembersForUser(c, session.UserId, true, true)
|
||||
var channelRoles []string
|
||||
if err == nil {
|
||||
if roles, ok := ids[channelID]; ok {
|
||||
@@ -134,7 +134,7 @@ func (a *App) SessionHasPermissionToChannels(c request.CTX, session model.Sessio
|
||||
return true
|
||||
}
|
||||
|
||||
ids, err := a.Srv().Store().Channel().GetAllChannelMembersForUser(session.UserId, true, true)
|
||||
ids, err := a.Srv().Store().Channel().GetAllChannelMembersForUser(c, session.UserId, true, true)
|
||||
var channelRoles []string
|
||||
for _, channelID := range channelIDs {
|
||||
if err == nil {
|
||||
@@ -266,7 +266,7 @@ func (a *App) HasPermissionToChannel(c request.CTX, askingUserId string, channel
|
||||
// We call GetAllChannelMembersForUser instead of just getting
|
||||
// a single member from the DB, because it's cache backed
|
||||
// and this is a very frequent call.
|
||||
ids, err := a.Srv().Store().Channel().GetAllChannelMembersForUser(askingUserId, true, true)
|
||||
ids, err := a.Srv().Store().Channel().GetAllChannelMembersForUser(c, askingUserId, true, true)
|
||||
var channelRoles []string
|
||||
if err == nil {
|
||||
if roles, ok := ids[channelID]; ok {
|
||||
|
||||
@@ -152,7 +152,7 @@ func TestSessionHasPermissionToChannel(t *testing.T) {
|
||||
|
||||
mockChannelStore := mocks.ChannelStore{}
|
||||
mockChannelStore.On("Get", mock.Anything, mock.Anything).Return(nil, fmt.Errorf("arbitrary error"))
|
||||
mockChannelStore.On("GetAllChannelMembersForUser", mock.Anything, mock.Anything, mock.Anything).Return(th.App.Srv().Store().Channel().GetAllChannelMembersForUser(th.BasicUser.Id, false, false))
|
||||
mockChannelStore.On("GetAllChannelMembersForUser", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(th.App.Srv().Store().Channel().GetAllChannelMembersForUser(th.Context, th.BasicUser.Id, false, false))
|
||||
mockChannelStore.On("ClearCaches").Return()
|
||||
mockStore.On("Channel").Return(&mockChannelStore)
|
||||
mockStore.On("FileInfo").Return(th.App.Srv().Store().FileInfo())
|
||||
@@ -214,7 +214,7 @@ func TestSessionHasPermissionToChannels(t *testing.T) {
|
||||
mockStore := mocks.Store{}
|
||||
mockChannelStore := mocks.ChannelStore{}
|
||||
mockChannelStore.On("Get", mock.Anything, mock.Anything).Return(nil, fmt.Errorf("arbitrary error"))
|
||||
mockChannelStore.On("GetAllChannelMembersForUser", mock.Anything, mock.Anything, mock.Anything).Return(th.App.Srv().Store().Channel().GetAllChannelMembersForUser(th.BasicUser.Id, false, false))
|
||||
mockChannelStore.On("GetAllChannelMembersForUser", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(th.App.Srv().Store().Channel().GetAllChannelMembersForUser(th.Context, th.BasicUser.Id, false, false))
|
||||
mockChannelStore.On("ClearCaches").Return()
|
||||
mockStore.On("Channel").Return(&mockChannelStore)
|
||||
mockStore.On("FileInfo").Return(th.App.Srv().Store().FileInfo())
|
||||
|
||||
@@ -1597,19 +1597,11 @@ func (a *App) AddUserToChannel(c request.CTX, user *model.User, channel *model.C
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// We are sending separate websocket events to the user added and to the channel
|
||||
// This is to get around potential cluster syncing issues where other nodes may not receive the most up to date channel members
|
||||
// There is likely some issue syncing these that needs to be looked at, but this is the current fix.
|
||||
message := model.NewWebSocketEvent(model.WebsocketEventUserAdded, "", channel.Id, "", map[string]bool{user.Id: true}, "")
|
||||
message := model.NewWebSocketEvent(model.WebsocketEventUserAdded, "", channel.Id, "", nil, "")
|
||||
message.Add("user_id", user.Id)
|
||||
message.Add("team_id", channel.TeamId)
|
||||
a.Publish(message)
|
||||
|
||||
userMessage := model.NewWebSocketEvent(model.WebsocketEventUserAdded, "", channel.Id, user.Id, nil, "")
|
||||
userMessage.Add("user_id", user.Id)
|
||||
userMessage.Add("team_id", channel.TeamId)
|
||||
a.Publish(userMessage)
|
||||
|
||||
return newMember, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -70,7 +70,7 @@ func (ps *PlatformService) ClearAllUsersSessionCacheLocal() {
|
||||
}
|
||||
|
||||
func (ps *PlatformService) ClearUserSessionCache(userID string) {
|
||||
ps.ClearUserSessionCacheLocal(userID)
|
||||
ps.ClearSessionCacheForUserSkipClusterSend(userID)
|
||||
|
||||
if ps.clusterIFace != nil {
|
||||
msg := &model.ClusterMessage{
|
||||
|
||||
@@ -26,6 +26,7 @@ import (
|
||||
"github.com/mattermost/mattermost/server/public/shared/i18n"
|
||||
"github.com/mattermost/mattermost/server/public/shared/mlog"
|
||||
"github.com/mattermost/mattermost/server/public/shared/request"
|
||||
"github.com/mattermost/mattermost/server/v8/channels/store/sqlstore"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -895,7 +896,12 @@ func (wc *WebConn) ShouldSendEvent(msg *model.WebSocketEvent) bool {
|
||||
}
|
||||
|
||||
if wc.allChannelMembers == nil {
|
||||
result, err := wc.Platform.Store.Channel().GetAllChannelMembersForUser(wc.UserId, false, false)
|
||||
result, err := wc.Platform.Store.Channel().GetAllChannelMembersForUser(
|
||||
sqlstore.RequestContextWithMaster(request.EmptyContext(wc.Platform.logger)),
|
||||
wc.UserId,
|
||||
false,
|
||||
false,
|
||||
)
|
||||
if err != nil {
|
||||
mlog.Error("webhub.shouldSendEvent.", mlog.Err(err))
|
||||
return false
|
||||
|
||||
@@ -197,7 +197,7 @@ func (ps *PlatformService) InvalidateCacheForChannelPosts(channelID string) {
|
||||
|
||||
func (ps *PlatformService) InvalidateCacheForUser(userID string) {
|
||||
ps.Store.Channel().InvalidateAllChannelMembersForUser(userID)
|
||||
ps.invalidateWebConnSessionCacheForUser(userID)
|
||||
ps.ClearUserSessionCache(userID)
|
||||
|
||||
ps.Store.User().InvalidateProfilesInChannelCacheByUser(userID)
|
||||
ps.Store.User().InvalidateProfileCacheForUser(userID)
|
||||
|
||||
@@ -2388,7 +2388,7 @@ func (a *App) GetViewUsersRestrictions(c request.CTX, userID string) (*model.Vie
|
||||
}
|
||||
}
|
||||
|
||||
userChannelMembers, err := a.Srv().Store().Channel().GetAllChannelMembersForUser(userID, true, true)
|
||||
userChannelMembers, err := a.Srv().Store().Channel().GetAllChannelMembersForUser(c, userID, true, true)
|
||||
if err != nil {
|
||||
return nil, model.NewAppError("GetViewUsersRestrictions", "app.channel.get_channels.get.app_error", nil, "", http.StatusInternalServerError).Wrap(err)
|
||||
}
|
||||
|
||||
Ссылка в новой задаче
Block a user