MM-21210: Add LRU cache for ChannelStore.GetMembersForUser (#13593)
Automatic Merge
Этот коммит содержится в:
коммит произвёл
mattermod
родитель
8b24b26cb0
Коммит
0361e8b97e
@@ -17,6 +17,7 @@ const (
|
||||
CLUSTER_EVENT_INVALIDATE_CACHE_FOR_CHANNEL_POSTS = "inv_channel_posts"
|
||||
CLUSTER_EVENT_INVALIDATE_CACHE_FOR_CHANNEL_MEMBERS_NOTIFY_PROPS = "inv_channel_members_notify_props"
|
||||
CLUSTER_EVENT_INVALIDATE_CACHE_FOR_CHANNEL_MEMBERS = "inv_channel_members"
|
||||
CLUSTER_EVENT_INVALIDATE_CACHE_FOR_CHANNEL_MEMBERS_FOR_USER = "inv_channel_members_user"
|
||||
CLUSTER_EVENT_INVALIDATE_CACHE_FOR_CHANNEL_BY_NAME = "inv_channel_name"
|
||||
CLUSTER_EVENT_INVALIDATE_CACHE_FOR_CHANNEL = "inv_channel"
|
||||
CLUSTER_EVENT_INVALIDATE_CACHE_FOR_CHANNEL_GUEST_COUNT = "inv_channel_guest_count"
|
||||
|
||||
3
services/cache/cache.go
поставляемый
3
services/cache/cache.go
поставляемый
@@ -31,6 +31,9 @@ type Cache interface {
|
||||
// Remove deletes the value for a key.
|
||||
Remove(key interface{})
|
||||
|
||||
// RemoveByPrefix deletes all keys containing the given prefix string.
|
||||
RemoveByPrefix(prefix string)
|
||||
|
||||
// Keys returns a slice of the keys in the cache.
|
||||
Keys() []interface{}
|
||||
|
||||
|
||||
19
services/cache/lru/lru.go
поставляемый
19
services/cache/lru/lru.go
поставляемый
@@ -12,6 +12,7 @@ package lru
|
||||
|
||||
import (
|
||||
"container/list"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
@@ -187,6 +188,24 @@ func (c *Cache) Remove(key interface{}) {
|
||||
}
|
||||
}
|
||||
|
||||
// RemoveByPrefix deletes all keys containing the given prefix string.
|
||||
func (c *Cache) RemoveByPrefix(prefix string) {
|
||||
c.lock.Lock()
|
||||
defer c.lock.Unlock()
|
||||
|
||||
for ent := c.evictList.Back(); ent != nil; ent = ent.Prev() {
|
||||
e := ent.Value.(*entry)
|
||||
if e.generation == c.currentGeneration {
|
||||
keyString := e.key.(string)
|
||||
if strings.HasPrefix(keyString, prefix) {
|
||||
if ent, ok := c.items[e.key]; ok {
|
||||
c.removeElement(ent)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Keys returns a slice of the keys in the cache, from oldest to newest.
|
||||
func (c *Cache) Keys() []interface{} {
|
||||
c.lock.RLock()
|
||||
|
||||
@@ -45,17 +45,29 @@ func (s *LocalCacheChannelStore) handleClusterInvalidateChannelById(msg *model.C
|
||||
}
|
||||
}
|
||||
|
||||
func (s *LocalCacheChannelStore) handleClusterInvalidateChannelMembersForUser(msg *model.ClusterMessage) {
|
||||
if msg.Data == CLEAR_CACHE_MESSAGE_DATA {
|
||||
s.rootStore.channelMembersForUserCache.Purge()
|
||||
return
|
||||
}
|
||||
|
||||
// Remove keys with prefix msg.Data
|
||||
s.rootStore.channelMembersForUserCache.RemoveByPrefix(msg.Data)
|
||||
}
|
||||
|
||||
func (s LocalCacheChannelStore) ClearCaches() {
|
||||
s.rootStore.doClearCacheCluster(s.rootStore.channelMemberCountsCache)
|
||||
s.rootStore.doClearCacheCluster(s.rootStore.channelPinnedPostCountsCache)
|
||||
s.rootStore.doClearCacheCluster(s.rootStore.channelGuestCountCache)
|
||||
s.rootStore.doClearCacheCluster(s.rootStore.channelByIdCache)
|
||||
s.rootStore.doClearCacheCluster(s.rootStore.channelMembersForUserCache)
|
||||
s.ChannelStore.ClearCaches()
|
||||
if s.rootStore.metrics != nil {
|
||||
s.rootStore.metrics.IncrementMemCacheInvalidationCounter("Channel Pinned Post Counts - Purge")
|
||||
s.rootStore.metrics.IncrementMemCacheInvalidationCounter("Channel Member Counts - Purge")
|
||||
s.rootStore.metrics.IncrementMemCacheInvalidationCounter("Channel Guest Count - Purge")
|
||||
s.rootStore.metrics.IncrementMemCacheInvalidationCounter("Channel - Purge")
|
||||
s.rootStore.metrics.IncrementMemCacheInvalidationCounter("Channel Members For User - Purge")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,6 +85,44 @@ func (s LocalCacheChannelStore) InvalidateMemberCount(channelId string) {
|
||||
}
|
||||
}
|
||||
|
||||
// invalidateMembersForUser removes all keys from channelMembersForUserCache
|
||||
// with the prefix of the given userID.
|
||||
// We cannot simply call doInvalidateCacheCluster because we need to remove
|
||||
// keys with a prefix rather than remove a single key.
|
||||
func (s LocalCacheChannelStore) invalidateMembersForUser(userId string) {
|
||||
s.rootStore.channelMembersForUserCache.RemoveByPrefix(userId)
|
||||
if s.rootStore.cluster != nil {
|
||||
msg := &model.ClusterMessage{
|
||||
Event: model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_CHANNEL_MEMBERS_FOR_USER,
|
||||
SendType: model.CLUSTER_SEND_BEST_EFFORT,
|
||||
Data: userId,
|
||||
}
|
||||
s.rootStore.cluster.SendClusterMessage(msg)
|
||||
}
|
||||
|
||||
if s.rootStore.metrics != nil {
|
||||
s.rootStore.metrics.IncrementMemCacheInvalidationCounter("Channel Members For User - Remove by UserId")
|
||||
}
|
||||
}
|
||||
|
||||
// invalidateMembersForAllUsers purges the entire channelMembersForUserCache cache.
|
||||
func (s LocalCacheChannelStore) invalidateMembersForAllUsers() {
|
||||
s.rootStore.channelMembersForUserCache.Purge()
|
||||
|
||||
if s.rootStore.cluster != nil {
|
||||
msg := &model.ClusterMessage{
|
||||
Event: model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_CHANNEL_MEMBERS_FOR_USER,
|
||||
SendType: model.CLUSTER_SEND_BEST_EFFORT,
|
||||
Data: CLEAR_CACHE_MESSAGE_DATA,
|
||||
}
|
||||
s.rootStore.cluster.SendClusterMessage(msg)
|
||||
}
|
||||
|
||||
if s.rootStore.metrics != nil {
|
||||
s.rootStore.metrics.IncrementMemCacheInvalidationCounter("Channel Members For User - Purge")
|
||||
}
|
||||
}
|
||||
|
||||
func (s LocalCacheChannelStore) InvalidateGuestCount(channelId string) {
|
||||
s.rootStore.doInvalidateCacheCluster(s.rootStore.channelGuestCountCache, channelId)
|
||||
if s.rootStore.metrics != nil {
|
||||
@@ -150,6 +200,92 @@ func (s LocalCacheChannelStore) GetPinnedPostCount(channelId string, allowFromCa
|
||||
return count, nil
|
||||
}
|
||||
|
||||
// SaveMember is a wrapper method for the underlying store which just takes
|
||||
// care of the cache invalidation.
|
||||
func (s LocalCacheChannelStore) SaveMember(member *model.ChannelMember) (*model.ChannelMember, *model.AppError) {
|
||||
defer s.invalidateMembersForUser(member.UserId)
|
||||
return s.ChannelStore.SaveMember(member)
|
||||
}
|
||||
|
||||
// UpdateMember is a wrapper method for the underlying store which just takes
|
||||
// care of the cache invalidation.
|
||||
func (s LocalCacheChannelStore) UpdateMember(member *model.ChannelMember) (*model.ChannelMember, *model.AppError) {
|
||||
defer s.invalidateMembersForUser(member.UserId)
|
||||
return s.ChannelStore.UpdateMember(member)
|
||||
}
|
||||
|
||||
// RemoveMember is a wrapper method for the underlying store which just takes
|
||||
// care of the cache invalidation.
|
||||
func (s LocalCacheChannelStore) RemoveMember(channelId, userId string) *model.AppError {
|
||||
defer s.invalidateMembersForUser(userId)
|
||||
return s.ChannelStore.RemoveMember(channelId, userId)
|
||||
}
|
||||
|
||||
// UpdateLastViewedAt is a wrapper method for the underlying store which just takes
|
||||
// care of the cache invalidation.
|
||||
func (s LocalCacheChannelStore) UpdateLastViewedAt(channelIds []string, userId string) (map[string]int64, *model.AppError) {
|
||||
defer s.invalidateMembersForUser(userId)
|
||||
return s.ChannelStore.UpdateLastViewedAt(channelIds, userId)
|
||||
}
|
||||
|
||||
// UpdateLastViewedAtPost is a wrapper method for the underlying store which just takes
|
||||
// care of the cache invalidation.
|
||||
func (s LocalCacheChannelStore) UpdateLastViewedAtPost(unreadPost *model.Post, userID string, mentionCount int) (*model.ChannelUnreadAt, *model.AppError) {
|
||||
defer s.invalidateMembersForUser(userID)
|
||||
return s.ChannelStore.UpdateLastViewedAtPost(unreadPost, userID, mentionCount)
|
||||
}
|
||||
|
||||
// PermanentDeleteMembersByChannel is a wrapper method for the underlying store which just takes
|
||||
// care of the cache invalidation.
|
||||
func (s LocalCacheChannelStore) PermanentDeleteMembersByChannel(channelId string) *model.AppError {
|
||||
defer s.invalidateMembersForAllUsers()
|
||||
return s.ChannelStore.PermanentDeleteMembersByChannel(channelId)
|
||||
}
|
||||
|
||||
// PermanentDeleteMembersByUser is a wrapper method for the underlying store which just takes
|
||||
// care of the cache invalidation.
|
||||
func (s LocalCacheChannelStore) PermanentDeleteMembersByUser(userId string) *model.AppError {
|
||||
defer s.invalidateMembersForUser(userId)
|
||||
return s.ChannelStore.PermanentDeleteMembersByUser(userId)
|
||||
}
|
||||
|
||||
// RemoveAllDeactivatedMembers is a wrapper method for the underlying store which just takes
|
||||
// care of the cache invalidation.
|
||||
func (s LocalCacheChannelStore) RemoveAllDeactivatedMembers(channelId string) *model.AppError {
|
||||
defer s.invalidateMembersForAllUsers()
|
||||
return s.ChannelStore.RemoveAllDeactivatedMembers(channelId)
|
||||
}
|
||||
|
||||
// ClearAllCustomRoleAssignments is a wrapper method for the underlying store which just takes
|
||||
// care of the cache invalidation.
|
||||
func (s LocalCacheChannelStore) ClearAllCustomRoleAssignments() *model.AppError {
|
||||
defer s.invalidateMembersForAllUsers()
|
||||
return s.ChannelStore.ClearAllCustomRoleAssignments()
|
||||
}
|
||||
|
||||
// IncrementMentionCount is a wrapper method for the underlying store which just takes
|
||||
// care of the cache invalidation.
|
||||
func (s LocalCacheChannelStore) IncrementMentionCount(channelId, userId string) *model.AppError {
|
||||
defer s.invalidateMembersForUser(userId)
|
||||
return s.ChannelStore.IncrementMentionCount(channelId, userId)
|
||||
}
|
||||
|
||||
// GetMembersForUser is a cache wrapper method for ChannelStore.
|
||||
func (s LocalCacheChannelStore) GetMembersForUser(teamId, userId string) (*model.ChannelMembers, *model.AppError) {
|
||||
key := userId + "-" + teamId
|
||||
if members := s.rootStore.doStandardReadCache(s.rootStore.channelMembersForUserCache, key); members != nil {
|
||||
return members.(*model.ChannelMembers), nil
|
||||
}
|
||||
|
||||
members, err := s.ChannelStore.GetMembersForUser(teamId, userId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
s.rootStore.doStandardAddToCache(s.rootStore.channelMembersForUserCache, key, members)
|
||||
return members, nil
|
||||
}
|
||||
|
||||
func (s LocalCacheChannelStore) Get(id string, allowFromCache bool) (*model.Channel, *model.AppError) {
|
||||
|
||||
if allowFromCache {
|
||||
|
||||
@@ -4,9 +4,10 @@
|
||||
package localcachelayer
|
||||
|
||||
import (
|
||||
"github.com/mattermost/mattermost-server/v5/model"
|
||||
"testing"
|
||||
|
||||
"github.com/mattermost/mattermost-server/v5/model"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
@@ -296,3 +297,66 @@ func TestChannelStoreChannel(t *testing.T) {
|
||||
mockStore.Channel().(*mocks.ChannelStore).AssertNumberOfCalls(t, "Get", 2)
|
||||
})
|
||||
}
|
||||
|
||||
func TestChannelStoreChannelMembersForUserCache(t *testing.T) {
|
||||
fakeChannelMembers := model.ChannelMembers([]model.ChannelMember{
|
||||
{
|
||||
UserId: "123",
|
||||
},
|
||||
})
|
||||
|
||||
t.Run("first call not cached, second cached and returning same data", func(t *testing.T) {
|
||||
mockStore := getMockStore()
|
||||
mockCacheProvider := getMockCacheProvider()
|
||||
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
|
||||
gotMembers, err := cachedStore.Channel().GetMembersForUser("teamId", "userId1")
|
||||
require.Nil(t, err)
|
||||
assert.Equal(t, &fakeChannelMembers, gotMembers)
|
||||
mockStore.Channel().(*mocks.ChannelStore).AssertNumberOfCalls(t, "GetMembersForUser", 1)
|
||||
|
||||
_, _ = cachedStore.Channel().GetMembersForUser("teamId", "userId1")
|
||||
mockStore.Channel().(*mocks.ChannelStore).AssertNumberOfCalls(t, "GetMembersForUser", 1)
|
||||
})
|
||||
|
||||
t.Run("first call not cached, invalidate, and then not cached again", func(t *testing.T) {
|
||||
mockStore := getMockStore()
|
||||
mockCacheProvider := getMockCacheProvider()
|
||||
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
|
||||
gotMembers, err := cachedStore.Channel().GetMembersForUser("teamId", "userId1")
|
||||
require.Nil(t, err)
|
||||
assert.Equal(t, &fakeChannelMembers, gotMembers)
|
||||
mockStore.Channel().(*mocks.ChannelStore).AssertNumberOfCalls(t, "GetMembersForUser", 1)
|
||||
|
||||
// invalidate
|
||||
cachedStore.Channel().(LocalCacheChannelStore).invalidateMembersForUser("userId1")
|
||||
|
||||
_, _ = cachedStore.Channel().GetMembersForUser("teamId", "userId1")
|
||||
mockStore.Channel().(*mocks.ChannelStore).AssertNumberOfCalls(t, "GetMembersForUser", 2)
|
||||
})
|
||||
|
||||
t.Run("cache multiple items, invalidate all, then nothing cached ", func(t *testing.T) {
|
||||
mockStore := getMockStore()
|
||||
mockCacheProvider := getMockCacheProvider()
|
||||
cachedStore := NewLocalCacheLayer(mockStore, nil, nil, mockCacheProvider)
|
||||
|
||||
gotMembers, err := cachedStore.Channel().GetMembersForUser("teamId", "userId1")
|
||||
require.Nil(t, err)
|
||||
assert.Equal(t, &fakeChannelMembers, gotMembers)
|
||||
mockStore.Channel().(*mocks.ChannelStore).AssertNumberOfCalls(t, "GetMembersForUser", 1)
|
||||
|
||||
gotMembers, err = cachedStore.Channel().GetMembersForUser("teamId", "userId2")
|
||||
require.Nil(t, err)
|
||||
assert.Equal(t, &fakeChannelMembers, gotMembers)
|
||||
mockStore.Channel().(*mocks.ChannelStore).AssertNumberOfCalls(t, "GetMembersForUser", 2)
|
||||
|
||||
// invalidate all
|
||||
cachedStore.Channel().(LocalCacheChannelStore).invalidateMembersForAllUsers()
|
||||
|
||||
_, _ = cachedStore.Channel().GetMembersForUser("teamId", "userId1")
|
||||
mockStore.Channel().(*mocks.ChannelStore).AssertNumberOfCalls(t, "GetMembersForUser", 3)
|
||||
_, _ = cachedStore.Channel().GetMembersForUser("teamId", "userId2")
|
||||
mockStore.Channel().(*mocks.ChannelStore).AssertNumberOfCalls(t, "GetMembersForUser", 4)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -35,6 +35,9 @@ const (
|
||||
CHANNEL_MEMBERS_COUNTS_CACHE_SIZE = model.CHANNEL_CACHE_SIZE
|
||||
CHANNEL_MEMBERS_COUNTS_CACHE_SEC = 30 * 60
|
||||
|
||||
CHANNEL_MEMBERS_FOR_USER_SIZE = model.CHANNEL_CACHE_SIZE
|
||||
CHANNEL_MEMBERS_FOR_USER_CACHE_SEC = 30 * 60
|
||||
|
||||
LAST_POSTS_CACHE_SIZE = 20000
|
||||
LAST_POSTS_CACHE_SEC = 30 * 60
|
||||
|
||||
@@ -59,34 +62,45 @@ const (
|
||||
|
||||
type LocalCacheStore struct {
|
||||
store.Store
|
||||
metrics einterfaces.MetricsInterface
|
||||
cluster einterfaces.ClusterInterface
|
||||
reaction LocalCacheReactionStore
|
||||
reactionCache cache.Cache
|
||||
role LocalCacheRoleStore
|
||||
roleCache cache.Cache
|
||||
scheme LocalCacheSchemeStore
|
||||
schemeCache cache.Cache
|
||||
emoji LocalCacheEmojiStore
|
||||
emojiCacheById cache.Cache
|
||||
emojiIdCacheByName cache.Cache
|
||||
metrics einterfaces.MetricsInterface
|
||||
cluster einterfaces.ClusterInterface
|
||||
|
||||
reaction LocalCacheReactionStore
|
||||
reactionCache cache.Cache
|
||||
|
||||
role LocalCacheRoleStore
|
||||
roleCache cache.Cache
|
||||
|
||||
scheme LocalCacheSchemeStore
|
||||
schemeCache cache.Cache
|
||||
|
||||
emoji LocalCacheEmojiStore
|
||||
emojiCacheById cache.Cache
|
||||
emojiIdCacheByName cache.Cache
|
||||
|
||||
channel LocalCacheChannelStore
|
||||
channelMemberCountsCache cache.Cache
|
||||
channelGuestCountCache cache.Cache
|
||||
channelPinnedPostCountsCache cache.Cache
|
||||
channelByIdCache cache.Cache
|
||||
webhook LocalCacheWebhookStore
|
||||
webhookCache cache.Cache
|
||||
post LocalCachePostStore
|
||||
postLastPostsCache cache.Cache
|
||||
lastPostTimeCache cache.Cache
|
||||
user LocalCacheUserStore
|
||||
userProfileByIdsCache cache.Cache
|
||||
profilesInChannelCache cache.Cache
|
||||
team LocalCacheTeamStore
|
||||
teamAllTeamIdsForUserCache cache.Cache
|
||||
termsOfService LocalCacheTermsOfServiceStore
|
||||
termsOfServiceCache cache.Cache
|
||||
channelMembersForUserCache cache.Cache
|
||||
|
||||
webhook LocalCacheWebhookStore
|
||||
webhookCache cache.Cache
|
||||
|
||||
post LocalCachePostStore
|
||||
postLastPostsCache cache.Cache
|
||||
lastPostTimeCache cache.Cache
|
||||
|
||||
user LocalCacheUserStore
|
||||
userProfileByIdsCache cache.Cache
|
||||
profilesInChannelCache cache.Cache
|
||||
|
||||
team LocalCacheTeamStore
|
||||
teamAllTeamIdsForUserCache cache.Cache
|
||||
|
||||
termsOfService LocalCacheTermsOfServiceStore
|
||||
termsOfServiceCache cache.Cache
|
||||
}
|
||||
|
||||
func NewLocalCacheLayer(baseStore store.Store, metrics einterfaces.MetricsInterface, cluster einterfaces.ClusterInterface, cacheProvider cache.Provider) LocalCacheStore {
|
||||
@@ -96,54 +110,80 @@ func NewLocalCacheLayer(baseStore store.Store, metrics einterfaces.MetricsInterf
|
||||
cluster: cluster,
|
||||
metrics: metrics,
|
||||
}
|
||||
|
||||
// Reactions
|
||||
localCacheStore.reactionCache = cacheProvider.NewCacheWithParams(REACTION_CACHE_SIZE, "Reaction", REACTION_CACHE_SEC, model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_REACTIONS)
|
||||
localCacheStore.reaction = LocalCacheReactionStore{ReactionStore: baseStore.Reaction(), rootStore: &localCacheStore}
|
||||
|
||||
// Roles
|
||||
localCacheStore.roleCache = cacheProvider.NewCacheWithParams(ROLE_CACHE_SIZE, "Role", ROLE_CACHE_SEC, model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_ROLES)
|
||||
localCacheStore.role = LocalCacheRoleStore{RoleStore: baseStore.Role(), rootStore: &localCacheStore}
|
||||
|
||||
// Schemes
|
||||
localCacheStore.schemeCache = cacheProvider.NewCacheWithParams(SCHEME_CACHE_SIZE, "Scheme", SCHEME_CACHE_SEC, model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_SCHEMES)
|
||||
localCacheStore.scheme = LocalCacheSchemeStore{SchemeStore: baseStore.Scheme(), rootStore: &localCacheStore}
|
||||
|
||||
// Webhooks
|
||||
localCacheStore.webhookCache = cacheProvider.NewCacheWithParams(WEBHOOK_CACHE_SIZE, "Webhook", WEBHOOK_CACHE_SEC, model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_WEBHOOKS)
|
||||
localCacheStore.webhook = LocalCacheWebhookStore{WebhookStore: baseStore.Webhook(), rootStore: &localCacheStore}
|
||||
|
||||
// Emojis
|
||||
localCacheStore.emojiCacheById = cacheProvider.NewCacheWithParams(EMOJI_CACHE_SIZE, "EmojiById", EMOJI_CACHE_SEC, model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_EMOJIS_BY_ID)
|
||||
localCacheStore.emojiIdCacheByName = cacheProvider.NewCacheWithParams(EMOJI_CACHE_SIZE, "EmojiByName", EMOJI_CACHE_SEC, model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_EMOJIS_ID_BY_NAME)
|
||||
localCacheStore.emoji = LocalCacheEmojiStore{EmojiStore: baseStore.Emoji(), rootStore: &localCacheStore}
|
||||
|
||||
// Channels
|
||||
localCacheStore.channelPinnedPostCountsCache = cacheProvider.NewCacheWithParams(CHANNEL_PINNEDPOSTS_COUNTS_CACHE_SIZE, "ChannelPinnedPostsCounts", CHANNEL_PINNEDPOSTS_COUNTS_CACHE_SEC, model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_CHANNEL_PINNEDPOSTS_COUNTS)
|
||||
localCacheStore.channelMemberCountsCache = cacheProvider.NewCacheWithParams(CHANNEL_MEMBERS_COUNTS_CACHE_SIZE, "ChannelMemberCounts", CHANNEL_MEMBERS_COUNTS_CACHE_SEC, model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_CHANNEL_MEMBER_COUNTS)
|
||||
localCacheStore.channelGuestCountCache = cacheProvider.NewCacheWithParams(CHANNEL_GUEST_COUNT_CACHE_SIZE, "ChannelGuestsCount", CHANNEL_GUEST_COUNT_CACHE_SEC, model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_CHANNEL_GUEST_COUNT)
|
||||
localCacheStore.channelByIdCache = cacheProvider.NewCacheWithParams(model.CHANNEL_CACHE_SIZE, "channelById", CHANNEL_CACHE_SEC, model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_CHANNEL)
|
||||
|
||||
localCacheStore.channelMembersForUserCache = cacheProvider.NewCacheWithParams(model.CHANNEL_CACHE_SIZE, "ChannelMembersForUser", CHANNEL_MEMBERS_FOR_USER_CACHE_SEC, model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_CHANNEL_MEMBERS_FOR_USER)
|
||||
localCacheStore.channel = LocalCacheChannelStore{ChannelStore: baseStore.Channel(), rootStore: &localCacheStore}
|
||||
|
||||
// Posts
|
||||
localCacheStore.postLastPostsCache = cacheProvider.NewCacheWithParams(LAST_POSTS_CACHE_SIZE, "LastPost", LAST_POSTS_CACHE_SEC, model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_LAST_POSTS)
|
||||
localCacheStore.lastPostTimeCache = cacheProvider.NewCacheWithParams(LAST_POST_TIME_CACHE_SIZE, "LastPostTime", LAST_POST_TIME_CACHE_SEC, model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_LAST_POST_TIME)
|
||||
|
||||
localCacheStore.post = LocalCachePostStore{PostStore: baseStore.Post(), rootStore: &localCacheStore}
|
||||
|
||||
// TOS
|
||||
localCacheStore.termsOfServiceCache = cacheProvider.NewCacheWithParams(TERMS_OF_SERVICE_CACHE_SIZE, "TermsOfService", TERMS_OF_SERVICE_CACHE_SEC, model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_TERMS_OF_SERVICE)
|
||||
localCacheStore.termsOfService = LocalCacheTermsOfServiceStore{TermsOfServiceStore: baseStore.TermsOfService(), rootStore: &localCacheStore}
|
||||
|
||||
// Users
|
||||
localCacheStore.userProfileByIdsCache = cacheProvider.NewCacheWithParams(USER_PROFILE_BY_ID_CACHE_SIZE, "UserProfileByIds", USER_PROFILE_BY_ID_SEC, model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_PROFILE_BY_IDS)
|
||||
localCacheStore.profilesInChannelCache = cacheProvider.NewCacheWithParams(PROFILES_IN_CHANNEL_CACHE_SIZE, "ProfilesInChannel", PROFILES_IN_CHANNEL_CACHE_SEC, model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_PROFILE_IN_CHANNEL)
|
||||
localCacheStore.user = LocalCacheUserStore{UserStore: baseStore.User(), rootStore: &localCacheStore}
|
||||
|
||||
// Teams
|
||||
localCacheStore.teamAllTeamIdsForUserCache = cacheProvider.NewCacheWithParams(TEAM_CACHE_SIZE, "Team", TEAM_CACHE_SEC, model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_TEAMS)
|
||||
localCacheStore.team = LocalCacheTeamStore{TeamStore: baseStore.Team(), rootStore: &localCacheStore}
|
||||
|
||||
if cluster != nil {
|
||||
cluster.RegisterClusterMessageHandler(model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_REACTIONS, localCacheStore.reaction.handleClusterInvalidateReaction)
|
||||
|
||||
cluster.RegisterClusterMessageHandler(model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_ROLES, localCacheStore.role.handleClusterInvalidateRole)
|
||||
|
||||
cluster.RegisterClusterMessageHandler(model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_SCHEMES, localCacheStore.scheme.handleClusterInvalidateScheme)
|
||||
cluster.RegisterClusterMessageHandler(model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_LAST_POST_TIME, localCacheStore.post.handleClusterInvalidateLastPostTime)
|
||||
|
||||
cluster.RegisterClusterMessageHandler(model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_WEBHOOKS, localCacheStore.webhook.handleClusterInvalidateWebhook)
|
||||
|
||||
cluster.RegisterClusterMessageHandler(model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_EMOJIS_BY_ID, localCacheStore.emoji.handleClusterInvalidateEmojiById)
|
||||
cluster.RegisterClusterMessageHandler(model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_EMOJIS_ID_BY_NAME, localCacheStore.emoji.handleClusterInvalidateEmojiIdByName)
|
||||
|
||||
cluster.RegisterClusterMessageHandler(model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_CHANNEL_PINNEDPOSTS_COUNTS, localCacheStore.channel.handleClusterInvalidateChannelPinnedPostCount)
|
||||
cluster.RegisterClusterMessageHandler(model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_CHANNEL_MEMBER_COUNTS, localCacheStore.channel.handleClusterInvalidateChannelMemberCounts)
|
||||
cluster.RegisterClusterMessageHandler(model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_CHANNEL_GUEST_COUNT, localCacheStore.channel.handleClusterInvalidateChannelGuestCounts)
|
||||
cluster.RegisterClusterMessageHandler(model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_CHANNEL, localCacheStore.channel.handleClusterInvalidateChannelById)
|
||||
cluster.RegisterClusterMessageHandler(model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_CHANNEL_MEMBERS_FOR_USER, localCacheStore.channel.handleClusterInvalidateChannelMembersForUser)
|
||||
|
||||
cluster.RegisterClusterMessageHandler(model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_LAST_POSTS, localCacheStore.post.handleClusterInvalidateLastPosts)
|
||||
cluster.RegisterClusterMessageHandler(model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_LAST_POST_TIME, localCacheStore.post.handleClusterInvalidateLastPostTime)
|
||||
|
||||
cluster.RegisterClusterMessageHandler(model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_TERMS_OF_SERVICE, localCacheStore.termsOfService.handleClusterInvalidateTermsOfService)
|
||||
|
||||
cluster.RegisterClusterMessageHandler(model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_PROFILE_BY_IDS, localCacheStore.user.handleClusterInvalidateScheme)
|
||||
cluster.RegisterClusterMessageHandler(model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_PROFILE_IN_CHANNEL, localCacheStore.user.handleClusterInvalidateProfilesInChannel)
|
||||
|
||||
cluster.RegisterClusterMessageHandler(model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_TEAMS, localCacheStore.team.handleClusterInvalidateTeam)
|
||||
}
|
||||
return localCacheStore
|
||||
@@ -243,6 +283,7 @@ func (s *LocalCacheStore) Invalidate() {
|
||||
s.doClearCacheCluster(s.emojiCacheById)
|
||||
s.doClearCacheCluster(s.emojiIdCacheByName)
|
||||
s.doClearCacheCluster(s.channelMemberCountsCache)
|
||||
s.doClearCacheCluster(s.channelMembersForUserCache)
|
||||
s.doClearCacheCluster(s.channelPinnedPostCountsCache)
|
||||
s.doClearCacheCluster(s.channelGuestCountCache)
|
||||
s.doClearCacheCluster(s.channelByIdCache)
|
||||
|
||||
@@ -80,6 +80,12 @@ func getMockCacheProvider() *mocks.CacheProvider {
|
||||
mock.AnythingOfType("int64"),
|
||||
mock.AnythingOfType("string")).Return(lru.New(128))
|
||||
|
||||
mockCacheProvider.On("NewCacheWithParams",
|
||||
mock.AnythingOfType("int"),
|
||||
"ChannelMembersForUser",
|
||||
mock.AnythingOfType("int64"),
|
||||
mock.AnythingOfType("string")).Return(lru.New(128))
|
||||
|
||||
mockCacheProvider.On("NewCacheWithParams",
|
||||
mock.AnythingOfType("int"),
|
||||
"LastPost",
|
||||
@@ -179,6 +185,13 @@ func getMockStore() *mocks.Store {
|
||||
mockPinnedPostsCount := int64(10)
|
||||
mockChannelStore.On("GetPinnedPostCount", "id", true).Return(mockPinnedPostsCount, nil)
|
||||
mockChannelStore.On("GetPinnedPostCount", "id", false).Return(mockPinnedPostsCount, nil)
|
||||
fakeChannelMembers := model.ChannelMembers([]model.ChannelMember{
|
||||
{
|
||||
UserId: "123",
|
||||
},
|
||||
})
|
||||
mockChannelStore.On("GetMembersForUser", "teamId", "userId1").Return(&fakeChannelMembers, nil)
|
||||
mockChannelStore.On("GetMembersForUser", "teamId", "userId2").Return(&fakeChannelMembers, nil)
|
||||
|
||||
fakePosts := &model.PostList{}
|
||||
fakeOptions := model.GetPostsOptions{ChannelId: "123", PerPage: 30}
|
||||
|
||||
@@ -1173,6 +1173,16 @@ func (_m *ChannelStore) InvalidateMemberCount(channelId string) {
|
||||
_m.Called(channelId)
|
||||
}
|
||||
|
||||
// InvalidateMembersForAllUsers provides a mock function with given fields:
|
||||
func (_m *ChannelStore) InvalidateMembersForAllUsers() {
|
||||
_m.Called()
|
||||
}
|
||||
|
||||
// InvalidateMembersForUser provides a mock function with given fields: userId
|
||||
func (_m *ChannelStore) InvalidateMembersForUser(userId string) {
|
||||
_m.Called(userId)
|
||||
}
|
||||
|
||||
// InvalidatePinnedPostCount provides a mock function with given fields: channelId
|
||||
func (_m *ChannelStore) InvalidatePinnedPostCount(channelId string) {
|
||||
_m.Called(channelId)
|
||||
|
||||
Ссылка в новой задаче
Block a user