MM-55295: Improve DB performance of some (Take 2) (#25865)

* Revert "Revert "MM-55295: Improve DB performance of some APIs (#25318)" (#25852)"

This reverts commit 077221a940.

* Fix the issue

```release-note
NONE
```

* lint fix

```release-note
NONE
```
This commit is contained in:
Agniva De Sarker
2024-01-11 10:18:36 +05:30
committed by GitHub
parent 43cca04f04
commit 1d879ed0f4
12 changed files with 232 additions and 56 deletions

View File

@@ -83,7 +83,6 @@ func (a *App) SessionHasPermissionToChannel(c request.CTX, session model.Session
}
ids, err := a.Srv().Store().Channel().GetAllChannelMembersForUser(session.UserId, true, true)
var channelRoles []string
if err == nil {
if roles, ok := ids[channelID]; ok {
@@ -260,17 +259,22 @@ func (a *App) HasPermissionToChannel(c request.CTX, askingUserId string, channel
return false
}
channelMember, err := a.GetChannelMember(c, channelID, askingUserId)
// 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)
var channelRoles []string
if err == nil {
roles := channelMember.GetRoles()
if a.RolesGrantPermission(roles, permission.Id) {
return true
if roles, ok := ids[channelID]; ok {
channelRoles = strings.Fields(roles)
if a.RolesGrantPermission(channelRoles, permission.Id) {
return true
}
}
}
var channel *model.Channel
channel, err = a.GetChannel(c, channelID)
if err == nil {
channel, appErr := a.GetChannel(c, channelID)
if appErr == nil {
return a.HasPermissionToTeam(c, askingUserId, channel.TeamId, permission)
}

View File

@@ -2063,6 +2063,21 @@ func (s *Server) getChannelMember(c request.CTX, channelID string, userID string
return channelMember, nil
}
func (s *Server) getChannelMemberLastViewedAt(c request.CTX, channelID string, userID string) (int64, *model.AppError) {
lastViewedAt, err := s.Store().Channel().GetMemberLastViewedAt(c.Context(), channelID, userID)
if err != nil {
var nfErr *store.ErrNotFound
switch {
case errors.As(err, &nfErr):
return 0, model.NewAppError("getChannelMemberLastViewedAt", MissingChannelMemberError, nil, "", http.StatusNotFound).Wrap(err)
default:
return 0, model.NewAppError("getChannelMemberLastViewedAt", "app.channel.get_member.app_error", nil, "", http.StatusInternalServerError).Wrap(err)
}
}
return lastViewedAt, nil
}
func (a *App) GetChannelMembersPage(c request.CTX, channelID string, page, perPage int) (model.ChannelMembers, *model.AppError) {
channelMembers, err := a.Srv().Store().Channel().GetMembers(channelID, page*perPage, perPage)
if err != nil {

View File

@@ -810,9 +810,9 @@ func (a *App) publishWebsocketEventForPermalinkPost(c request.CTX, post *model.P
return false, err
}
channelMembers, err := a.GetChannelMembersPage(c, post.ChannelId, 0, 10000000)
if err != nil {
return false, err
userIDs, nErr := a.Srv().Store().Channel().GetAllChannelMemberIdsByChannelId(post.ChannelId)
if nErr != nil {
return false, model.NewAppError("publishWebsocketEventForPermalinkPost", "app.channel.get_members.app_error", nil, "", http.StatusInternalServerError).Wrap(err)
}
permalinkPreviewedChannel, err := a.GetChannel(c, previewedPost.ChannelId)
@@ -827,19 +827,19 @@ func (a *App) publishWebsocketEventForPermalinkPost(c request.CTX, post *model.P
originalEmbeds := post.Metadata.Embeds
originalProps := post.GetProps()
permalinkPreviewedPost := post.GetPreviewPost()
for _, cm := range channelMembers {
for _, userID := range userIDs {
if permalinkPreviewedPost != nil {
post.Metadata.Embeds = originalEmbeds
post.SetProps(originalProps)
}
postForUser := a.sanitizePostMetadataForUserAndChannel(c, post, permalinkPreviewedPost, permalinkPreviewedChannel, cm.UserId)
postForUser := a.sanitizePostMetadataForUserAndChannel(c, post, permalinkPreviewedPost, permalinkPreviewedChannel, userID)
// Using DeepCopy here to avoid a race condition
// between publishing the event and setting the "post" data value below.
messageCopy := message.DeepCopy()
broadcastCopy := messageCopy.GetBroadcast()
broadcastCopy.UserId = cm.UserId
broadcastCopy.UserId = userID
messageCopy.SetBroadcast(broadcastCopy)
postJSON, jsonErr := postForUser.ToJSON()
@@ -1292,15 +1292,15 @@ func (a *App) AddCursorIdsForPostList(originalList *model.PostList, afterPost, b
originalList.PrevPostId = prevPostId
}
func (a *App) GetPostsForChannelAroundLastUnread(c request.CTX, channelID, userID string, limitBefore, limitAfter int, skipFetchThreads bool, collapsedThreads, collapsedThreadsExtended bool) (*model.PostList, *model.AppError) {
var member *model.ChannelMember
var lastViewedAt int64
var err *model.AppError
if member, err = a.GetChannelMember(c, channelID, userID); err != nil {
if lastViewedAt, err = a.Srv().getChannelMemberLastViewedAt(c, channelID, userID); err != nil {
return nil, err
} else if member.LastViewedAt == 0 {
} else if lastViewedAt == 0 {
return model.NewPostList(), nil
}
lastUnreadPostId, err := a.GetPostIdAfterTime(channelID, member.LastViewedAt, collapsedThreads)
lastUnreadPostId, err := a.GetPostIdAfterTime(channelID, lastViewedAt, collapsedThreads)
if err != nil {
return nil, err
} else if lastUnreadPostId == "" {
@@ -1870,9 +1870,9 @@ func (a *App) countThreadMentions(c request.CTX, user *model.User, post *model.P
// countMentionsFromPost returns the number of posts in the post's channel that mention the user after and including the
// given post.
func (a *App) countMentionsFromPost(c request.CTX, user *model.User, post *model.Post) (int, int, int, *model.AppError) {
channel, err := a.GetChannel(c, post.ChannelId)
if err != nil {
return 0, 0, 0, err
channel, appErr := a.GetChannel(c, post.ChannelId)
if appErr != nil {
return 0, 0, 0, appErr
}
if channel.Type == model.ChannelTypeDirect || channel.Type == model.ChannelTypeGroup {
@@ -1893,15 +1893,15 @@ func (a *App) countMentionsFromPost(c request.CTX, user *model.User, post *model
return count, countRoot, urgentCount, nil
}
channelMember, err := a.GetChannelMember(c, channel.Id, user.Id)
members, err := a.Srv().Store().Channel().GetAllChannelMembersNotifyPropsForChannel(channel.Id, true)
if err != nil {
return 0, 0, 0, err
return 0, 0, 0, model.NewAppError("countMentionsFromPost", "app.channel.count_posts_since.app_error", nil, "", http.StatusInternalServerError).Wrap(err)
}
keywords := MentionKeywords{}
keywords.AddUser(
user,
channelMember.NotifyProps,
members[user.Id],
&model.Status{Status: model.StatusOnline}, // Assume the user is online since they would've triggered this
true, // Assume channel mentions are always allowed for simplicity
)
@@ -1911,9 +1911,9 @@ func (a *App) countMentionsFromPost(c request.CTX, user *model.User, post *model
// A mapping of thread root IDs to whether or not a post in that thread mentions the user
mentionedByThread := make(map[string]bool)
thread, err := a.GetPostThread(post.Id, model.GetPostsOptions{}, user.Id)
if err != nil {
return 0, 0, 0, err
thread, appErr := a.GetPostThread(post.Id, model.GetPostsOptions{}, user.Id)
if appErr != nil {
return 0, 0, 0, appErr
}
count := 0

View File

@@ -965,16 +965,16 @@ func (s *OpenTracingLayerChannelStore) GetAll(teamID string) ([]*model.Channel,
return result, err
}
func (s *OpenTracingLayerChannelStore) GetAllChannelMembersById(id string) ([]string, error) {
func (s *OpenTracingLayerChannelStore) GetAllChannelMemberIdsByChannelId(id string) ([]string, error) {
origCtx := s.Root.Store.Context()
span, newCtx := tracing.StartSpanWithParentByContext(s.Root.Store.Context(), "ChannelStore.GetAllChannelMembersById")
span, newCtx := tracing.StartSpanWithParentByContext(s.Root.Store.Context(), "ChannelStore.GetAllChannelMemberIdsByChannelId")
s.Root.Store.SetContext(newCtx)
defer func() {
s.Root.Store.SetContext(origCtx)
}()
defer span.Finish()
result, err := s.ChannelStore.GetAllChannelMembersById(id)
result, err := s.ChannelStore.GetAllChannelMemberIdsByChannelId(id)
if err != nil {
span.LogFields(spanlog.Error(err))
ext.Error.Set(span, true)
@@ -1572,6 +1572,24 @@ func (s *OpenTracingLayerChannelStore) GetMemberForPost(postID string, userID st
return result, err
}
func (s *OpenTracingLayerChannelStore) GetMemberLastViewedAt(ctx context.Context, channelID string, userID string) (int64, error) {
origCtx := s.Root.Store.Context()
span, newCtx := tracing.StartSpanWithParentByContext(s.Root.Store.Context(), "ChannelStore.GetMemberLastViewedAt")
s.Root.Store.SetContext(newCtx)
defer func() {
s.Root.Store.SetContext(origCtx)
}()
defer span.Finish()
result, err := s.ChannelStore.GetMemberLastViewedAt(ctx, channelID, userID)
if err != nil {
span.LogFields(spanlog.Error(err))
ext.Error.Set(span, true)
}
return result, err
}
func (s *OpenTracingLayerChannelStore) GetMembers(channelID string, offset int, limit int) (model.ChannelMembers, error) {
origCtx := s.Root.Store.Context()
span, newCtx := tracing.StartSpanWithParentByContext(s.Root.Store.Context(), "ChannelStore.GetMembers")

View File

@@ -1049,11 +1049,11 @@ func (s *RetryLayerChannelStore) GetAll(teamID string) ([]*model.Channel, error)
}
func (s *RetryLayerChannelStore) GetAllChannelMembersById(id string) ([]string, error) {
func (s *RetryLayerChannelStore) GetAllChannelMemberIdsByChannelId(id string) ([]string, error) {
tries := 0
for {
result, err := s.ChannelStore.GetAllChannelMembersById(id)
result, err := s.ChannelStore.GetAllChannelMemberIdsByChannelId(id)
if err == nil {
return result, nil
}
@@ -1748,6 +1748,27 @@ func (s *RetryLayerChannelStore) GetMemberForPost(postID string, userID string,
}
func (s *RetryLayerChannelStore) GetMemberLastViewedAt(ctx context.Context, channelID string, userID string) (int64, error) {
tries := 0
for {
result, err := s.ChannelStore.GetMemberLastViewedAt(ctx, channelID, userID)
if err == nil {
return result, nil
}
if !isRepeatableError(err) {
return result, err
}
tries++
if tries >= 3 {
err = errors.Wrap(err, "giving up after 3 consecutive repeatable transaction failures")
return result, err
}
timepkg.Sleep(100 * timepkg.Millisecond)
}
}
func (s *RetryLayerChannelStore) GetMembers(channelID string, offset int, limit int) (model.ChannelMembers, error) {
tries := 0

View File

@@ -40,7 +40,7 @@ func (c *SearchChannelStore) indexChannel(rctx request.CTX, channel *model.Chann
var userIDs, teamMemberIDs []string
var err error
if channel.Type == model.ChannelTypePrivate {
userIDs, err = c.GetAllChannelMembersById(channel.Id)
userIDs, err = c.GetAllChannelMemberIdsByChannelId(channel.Id)
if err != nil {
rctx.Logger().Warn("Encountered error while indexing channel", mlog.String("channel_id", channel.Id), mlog.Err(err))
return

View File

@@ -1126,26 +1126,16 @@ func (s SqlChannelStore) GetChannelsByUser(userId string, includeDeleted bool, l
return channels, nil
}
func (s SqlChannelStore) GetAllChannelMembersById(channelID string) ([]string, error) {
sql, args, err := s.channelMembersForTeamWithSchemeSelectQuery.Where(sq.Eq{
"ChannelId": channelID,
}).ToSql()
if err != nil {
return nil, errors.Wrap(err, "GetAllChannelMembersById_ToSql")
}
dbMembers := channelMemberWithSchemeRolesList{}
err = s.GetReplicaX().Select(&dbMembers, sql, args...)
func (s SqlChannelStore) GetAllChannelMemberIdsByChannelId(channelID string) ([]string, error) {
userIDs := []string{}
err := s.GetReplicaX().Select(&userIDs, `SELECT UserId
FROM ChannelMembers
WHERE ChannelId=?`, channelID)
if err != nil {
return nil, errors.Wrapf(err, "failed to get ChannelMembers with channelID=%s", channelID)
}
res := make([]string, len(dbMembers))
for i, member := range dbMembers.ToModel() {
res[i] = member.UserId
}
return res, nil
return userIDs, nil
}
func (s SqlChannelStore) GetAllChannels(offset, limit int, opts store.ChannelSearchOpts) (model.ChannelListWithTeamData, error) {
@@ -2070,6 +2060,20 @@ func (s SqlChannelStore) GetMember(ctx context.Context, channelID string, userID
return dbMember.ToModel(), nil
}
func (s SqlChannelStore) GetMemberLastViewedAt(ctx context.Context, channelID string, userID string) (int64, error) {
var lastViewedAt int64
if err := s.DBXFromContext(ctx).Get(&lastViewedAt, `SELECT COALESCE(LastViewedAt, 0) AS LastViewedAt
FROM ChannelMembers
WHERE ChannelId=? AND UserId=?`, channelID, userID); err != nil {
if err == sql.ErrNoRows {
return 0, store.NewErrNotFound("LastViewedAt", fmt.Sprintf("channelId=%s, userId=%s", channelID, userID))
}
return 0, errors.Wrapf(err, "failed to get lastViewedAt with channelId=%s and userId=%s", channelID, userID)
}
return lastViewedAt, nil
}
func (s SqlChannelStore) InvalidateAllChannelMembersForUser(userId string) {
allChannelMembersForUserCache.Remove(userId)
allChannelMembersForUserCache.Remove(userId + "_deleted")

View File

@@ -205,7 +205,7 @@ type ChannelStore interface {
GetDeleted(team_id string, offset int, limit int, userID string) (model.ChannelList, error)
GetChannels(teamID, userID string, opts *model.ChannelSearchOpts) (model.ChannelList, error)
GetChannelsByUser(userID string, includeDeleted bool, lastDeleteAt, pageSize int, fromChannelID string) (model.ChannelList, error)
GetAllChannelMembersById(id string) ([]string, error)
GetAllChannelMemberIdsByChannelId(id string) ([]string, error)
GetAllChannels(page, perPage int, opts ChannelSearchOpts) (model.ChannelListWithTeamData, error)
GetAllChannelsCount(opts ChannelSearchOpts) (int64, error)
GetMoreChannels(teamID string, userID string, offset int, limit int) (model.ChannelList, error)
@@ -227,6 +227,7 @@ type ChannelStore interface {
UpdateMemberNotifyProps(channelID, userID string, props map[string]string) (*model.ChannelMember, error)
GetMembers(channelID string, offset, limit int) (model.ChannelMembers, error)
GetMember(ctx context.Context, channelID string, userID string) (*model.ChannelMember, error)
GetMemberLastViewedAt(ctx context.Context, channelID string, userID string) (int64, error)
GetChannelMembersTimezones(channelID string) ([]model.StringMap, error)
GetAllChannelMembersForUser(userID string, allowFromCache bool, includeDeleted bool) (map[string]string, error)
GetChannelsMemberCount(channelIDs []string) (map[string]int64, error)

View File

@@ -110,6 +110,7 @@ func TestChannelStore(t *testing.T, rctx request.CTX, ss store.Store, s SqlStore
t.Run("IncrementMentionCount", func(t *testing.T) { testChannelStoreIncrementMentionCount(t, rctx, ss) })
t.Run("UpdateChannelMember", func(t *testing.T) { testUpdateChannelMember(t, rctx, ss) })
t.Run("GetMember", func(t *testing.T) { testGetMember(t, rctx, ss) })
t.Run("GetMemberLastViewedAt", func(t *testing.T) { testGetMemberLastViewedAt(t, rctx, ss) })
t.Run("GetMemberForPost", func(t *testing.T) { testChannelStoreGetMemberForPost(t, rctx, ss) })
t.Run("GetMemberCount", func(t *testing.T) { testGetMemberCount(t, rctx, ss) })
t.Run("GetMemberCountsByGroup", func(t *testing.T) { testGetMemberCountsByGroup(t, rctx, ss) })
@@ -246,6 +247,10 @@ func testChannelStoreSaveDirectChannel(t *testing.T, rctx request.CTX, ss store.
require.NoError(t, nErr)
require.Len(t, members, 2, "should have saved 2 members")
userIDs, nErr := ss.Channel().GetAllChannelMemberIdsByChannelId(o1.Id)
require.NoError(t, nErr)
require.ElementsMatch(t, []string{u1.Id, u2.Id}, userIDs)
_, nErr = ss.Channel().SaveDirectChannel(rctx, &o1, &m1, &m2)
require.Error(t, nErr, "shouldn't be a able to update from save")
@@ -282,6 +287,10 @@ func testChannelStoreSaveDirectChannel(t *testing.T, rctx request.CTX, ss store.
require.NoError(t, nErr)
require.Len(t, members, 1, "should have saved just 1 member")
userIDs, nErr = ss.Channel().GetAllChannelMemberIdsByChannelId(o1.Id)
require.NoError(t, nErr)
require.ElementsMatch(t, []string{u1.Id}, userIDs)
// Manually truncate Channels table until testlib can handle cleanups
s.GetMasterX().Exec("TRUNCATE Channels")
}
@@ -4892,6 +4901,62 @@ func testGetMember(t *testing.T, rctx request.CTX, ss store.Store) {
ss.Channel().InvalidateCacheForChannelMembersNotifyProps(c2.Id)
}
func testGetMemberLastViewedAt(t *testing.T, rctx request.CTX, ss store.Store) {
userId := model.NewId()
c1 := &model.Channel{
TeamId: model.NewId(),
DisplayName: model.NewId(),
Name: model.NewId(),
Type: model.ChannelTypeOpen,
}
_, nErr := ss.Channel().Save(c1, -1)
require.NoError(t, nErr)
c2 := &model.Channel{
TeamId: c1.TeamId,
DisplayName: model.NewId(),
Name: model.NewId(),
Type: model.ChannelTypeOpen,
}
_, nErr = ss.Channel().Save(c2, -1)
require.NoError(t, nErr)
m1 := &model.ChannelMember{
ChannelId: c1.Id,
UserId: userId,
NotifyProps: model.GetDefaultChannelNotifyProps(),
LastViewedAt: int64(100),
}
_, err := ss.Channel().SaveMember(m1)
require.NoError(t, err)
m2 := &model.ChannelMember{
ChannelId: c2.Id,
UserId: userId,
NotifyProps: model.GetDefaultChannelNotifyProps(),
LastViewedAt: int64(200),
}
_, err = ss.Channel().SaveMember(m2)
require.NoError(t, err)
_, err = ss.Channel().GetMemberLastViewedAt(context.Background(), model.NewId(), userId)
require.Error(t, err, "should've failed to get member for non-existent channel")
_, err = ss.Channel().GetMemberLastViewedAt(context.Background(), c1.Id, model.NewId())
require.Error(t, err, "should've failed to get member for non-existent user")
lvAt, err := ss.Channel().GetMemberLastViewedAt(context.Background(), c1.Id, userId)
require.NoError(t, err, "shouldn't have errored when getting member", err)
require.Equal(t, m1.LastViewedAt, lvAt, "should've gotten LastViewedAt of channel 1")
lvAt, err = ss.Channel().GetMemberLastViewedAt(context.Background(), c2.Id, userId)
require.NoError(t, err, "shouldn't have errored when getting member", err)
require.Equal(t, m2.LastViewedAt, lvAt, "should've gotten gotten LastViewedAt of channel 2")
ss.Channel().InvalidateCacheForChannelMembersNotifyProps(c2.Id)
}
func testChannelStoreGetMemberForPost(t *testing.T, rctx request.CTX, ss store.Store) {
ch := &model.Channel{
TeamId: model.NewId(),
@@ -7477,6 +7542,10 @@ func testChannelStoreRemoveAllDeactivatedMembers(t *testing.T, rctx request.CTX,
assert.NoError(t, err)
assert.Len(t, d1, 3)
userIDs, nErr := ss.Channel().GetAllChannelMemberIdsByChannelId(c1.Id)
require.NoError(t, nErr)
require.ElementsMatch(t, []string{u1.Id, u2.Id, u3.Id}, userIDs)
// Deactivate users 1 & 2.
u1.DeleteAt = model.GetMillis()
u2.DeleteAt = model.GetMillis()
@@ -7494,6 +7563,10 @@ func testChannelStoreRemoveAllDeactivatedMembers(t *testing.T, rctx request.CTX,
assert.Len(t, d2, 1)
assert.Equal(t, u3.Id, d2[0].UserId)
userIDs, nErr = ss.Channel().GetAllChannelMemberIdsByChannelId(c1.Id)
require.NoError(t, nErr)
require.ElementsMatch(t, []string{u3.Id}, userIDs)
// Manually truncate Channels table until testlib can handle cleanups
s.GetMasterX().Exec("TRUNCATE Channels")
}

View File

@@ -432,8 +432,8 @@ func (_m *ChannelStore) GetAll(teamID string) ([]*model.Channel, error) {
return r0, r1
}
// GetAllChannelMembersById provides a mock function with given fields: id
func (_m *ChannelStore) GetAllChannelMembersById(id string) ([]string, error) {
// GetAllChannelMemberIdsByChannelId provides a mock function with given fields: id
func (_m *ChannelStore) GetAllChannelMemberIdsByChannelId(id string) ([]string, error) {
ret := _m.Called(id)
var r0 []string
@@ -1314,6 +1314,30 @@ func (_m *ChannelStore) GetMemberForPost(postID string, userID string, includeAr
return r0, r1
}
// GetMemberLastViewedAt provides a mock function with given fields: ctx, channelID, userID
func (_m *ChannelStore) GetMemberLastViewedAt(ctx context.Context, channelID string, userID string) (int64, error) {
ret := _m.Called(ctx, channelID, userID)
var r0 int64
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, string, string) (int64, error)); ok {
return rf(ctx, channelID, userID)
}
if rf, ok := ret.Get(0).(func(context.Context, string, string) int64); ok {
r0 = rf(ctx, channelID, userID)
} else {
r0 = ret.Get(0).(int64)
}
if rf, ok := ret.Get(1).(func(context.Context, string, string) error); ok {
r1 = rf(ctx, channelID, userID)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// GetMembers provides a mock function with given fields: channelID, offset, limit
func (_m *ChannelStore) GetMembers(channelID string, offset int, limit int) (model.ChannelMembers, error) {
ret := _m.Called(channelID, offset, limit)

View File

@@ -917,10 +917,10 @@ func (s *TimerLayerChannelStore) GetAll(teamID string) ([]*model.Channel, error)
return result, err
}
func (s *TimerLayerChannelStore) GetAllChannelMembersById(id string) ([]string, error) {
func (s *TimerLayerChannelStore) GetAllChannelMemberIdsByChannelId(id string) ([]string, error) {
start := time.Now()
result, err := s.ChannelStore.GetAllChannelMembersById(id)
result, err := s.ChannelStore.GetAllChannelMemberIdsByChannelId(id)
elapsed := float64(time.Since(start)) / float64(time.Second)
if s.Root.Metrics != nil {
@@ -928,7 +928,7 @@ func (s *TimerLayerChannelStore) GetAllChannelMembersById(id string) ([]string,
if err == nil {
success = "true"
}
s.Root.Metrics.ObserveStoreMethodDuration("ChannelStore.GetAllChannelMembersById", success, elapsed)
s.Root.Metrics.ObserveStoreMethodDuration("ChannelStore.GetAllChannelMemberIdsByChannelId", success, elapsed)
}
return result, err
}
@@ -1461,6 +1461,22 @@ func (s *TimerLayerChannelStore) GetMemberForPost(postID string, userID string,
return result, err
}
func (s *TimerLayerChannelStore) GetMemberLastViewedAt(ctx context.Context, channelID string, userID string) (int64, error) {
start := time.Now()
result, err := s.ChannelStore.GetMemberLastViewedAt(ctx, channelID, userID)
elapsed := float64(time.Since(start)) / float64(time.Second)
if s.Root.Metrics != nil {
success := "false"
if err == nil {
success = "true"
}
s.Root.Metrics.ObserveStoreMethodDuration("ChannelStore.GetMemberLastViewedAt", success, elapsed)
}
return result, err
}
func (s *TimerLayerChannelStore) GetMembers(channelID string, offset int, limit int) (model.ChannelMembers, error) {
start := time.Now()

View File

@@ -526,7 +526,7 @@ func (worker *BleveIndexerWorker) BulkIndexChannels(logger mlog.LoggerIFace, cha
var userIDs []string
var err error
if channel.Type == model.ChannelTypePrivate {
userIDs, err = worker.jobServer.Store.Channel().GetAllChannelMembersById(channel.Id)
userIDs, err = worker.jobServer.Store.Channel().GetAllChannelMemberIdsByChannelId(channel.Id)
if err != nil {
return nil, model.NewAppError("BleveIndexerWorker.BulkIndexChannels", "bleveengine.indexer.do_job.bulk_index_channels.batch_error", nil, "", http.StatusInternalServerError).Wrap(err)
}