From 0f5d160131afce750c5f0ec10027463d2282fd2d Mon Sep 17 00:00:00 2001 From: Agniva De Sarker Date: Tue, 10 Dec 2024 11:08:17 +0530 Subject: [PATCH] MM-62077: Fix cluster broadcast for LRU caches (#29488) We were incorrectly not broadcasting status cache updates inspite of that being an LRU cache. We were also not doing it for profilesInChannel cache. Now we fix it by properly checking the invalidationEvent which is something local to the cache itself rather than the cache provider. https://mattermost.atlassian.net/browse/MM-62077 ```release-note NONE ``` --- .../channels/app/platform/cluster_handlers.go | 2 +- server/channels/app/platform/status.go | 2 +- .../channels/store/localcachelayer/layer.go | 6 ++-- .../store/localcachelayer/layer_test.go | 34 +++++++++++++++++++ 4 files changed, 39 insertions(+), 5 deletions(-) diff --git a/server/channels/app/platform/cluster_handlers.go b/server/channels/app/platform/cluster_handlers.go index ae36e28889..b6b56da124 100644 --- a/server/channels/app/platform/cluster_handlers.go +++ b/server/channels/app/platform/cluster_handlers.go @@ -134,7 +134,7 @@ func (ps *PlatformService) InvalidateAllCachesSkipSend() { func (ps *PlatformService) InvalidateAllCaches() *model.AppError { ps.InvalidateAllCachesSkipSend() - if ps.clusterIFace != nil && *ps.Config().CacheSettings.CacheType == model.CacheTypeLRU { + if ps.clusterIFace != nil { msg := &model.ClusterMessage{ Event: model.ClusterEventInvalidateAllCaches, SendType: model.ClusterSendReliable, diff --git a/server/channels/app/platform/status.go b/server/channels/app/platform/status.go index b15e3ace8a..5aee2f3abb 100644 --- a/server/channels/app/platform/status.go +++ b/server/channels/app/platform/status.go @@ -21,7 +21,7 @@ func (ps *PlatformService) AddStatusCacheSkipClusterSend(status *model.Status) { func (ps *PlatformService) AddStatusCache(status *model.Status) { ps.AddStatusCacheSkipClusterSend(status) - if ps.Cluster() != nil && *ps.Config().CacheSettings.CacheType == model.CacheTypeLRU { + if ps.Cluster() != nil { statusJSON, err := json.Marshal(status) if err != nil { ps.logger.Warn("Failed to encode status to JSON", mlog.Err(err)) diff --git a/server/channels/store/localcachelayer/layer.go b/server/channels/store/localcachelayer/layer.go index 1003a01d61..a489ab8226 100644 --- a/server/channels/store/localcachelayer/layer.go +++ b/server/channels/store/localcachelayer/layer.go @@ -448,7 +448,7 @@ func (s *LocalCacheStore) doInvalidateCacheCluster(cache cache.Cache, key string if err != nil { s.logger.Warn("Error while removing cache entry", mlog.Err(err), mlog.String("cache_name", cache.Name())) } - if s.cluster != nil && s.cacheType == model.CacheTypeLRU { + if s.cluster != nil && cache.GetInvalidateClusterEvent() != model.ClusterEventNone { msg := &model.ClusterMessage{ Event: cache.GetInvalidateClusterEvent(), SendType: model.ClusterSendBestEffort, @@ -466,7 +466,7 @@ func (s *LocalCacheStore) doMultiInvalidateCacheCluster(cache cache.Cache, keys if err != nil { s.logger.Warn("Error while removing cache entry", mlog.Err(err), mlog.String("cache_name", cache.Name())) } - if s.cluster != nil && s.cacheType == model.CacheTypeLRU { + if s.cluster != nil && cache.GetInvalidateClusterEvent() != model.ClusterEventNone { for _, key := range keys { msg := &model.ClusterMessage{ Event: cache.GetInvalidateClusterEvent(), @@ -538,7 +538,7 @@ func (s *LocalCacheStore) doClearCacheCluster(cache cache.Cache) { if err != nil { s.logger.Warn("Error while purging cache", mlog.Err(err), mlog.String("cache_name", cache.Name())) } - if s.cluster != nil && s.cacheType == model.CacheTypeLRU { + if s.cluster != nil && cache.GetInvalidateClusterEvent() != model.ClusterEventNone { msg := &model.ClusterMessage{ Event: cache.GetInvalidateClusterEvent(), SendType: model.ClusterSendBestEffort, diff --git a/server/channels/store/localcachelayer/layer_test.go b/server/channels/store/localcachelayer/layer_test.go index 453337b5d6..b02c2f5659 100644 --- a/server/channels/store/localcachelayer/layer_test.go +++ b/server/channels/store/localcachelayer/layer_test.go @@ -14,7 +14,10 @@ import ( "github.com/mattermost/mattermost/server/v8/channels/store" "github.com/mattermost/mattermost/server/v8/channels/store/sqlstore" "github.com/mattermost/mattermost/server/v8/channels/store/storetest" + "github.com/mattermost/mattermost/server/v8/channels/testlib" "github.com/mattermost/mattermost/server/v8/platform/services/cache" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "golang.org/x/sync/errgroup" ) @@ -148,3 +151,34 @@ func tearDownStores() { wg.Wait() }) } + +func TestClearCacheCluster(t *testing.T) { + cluster := &testlib.FakeClusterInterface{} + lc := &LocalCacheStore{ + cluster: cluster, + } + + c := cache.NewLRU(&cache.CacheOptions{ + Size: 10, + Name: "test", + InvalidateClusterEvent: model.ClusterEventInvalidateCacheForRoles, + }) + + lc.doClearCacheCluster(c) + assert.Len(t, cluster.GetMessages(), 1) + expectedMsg := &model.ClusterMessage{ + Event: model.ClusterEventInvalidateCacheForRoles, + SendType: model.ClusterSendBestEffort, + Data: clearCacheMessageData, + } + require.Equal(t, expectedMsg, cluster.GetMessages()[0]) + + c = cache.NewLRU(&cache.CacheOptions{ + Size: 10, + Name: "test", + InvalidateClusterEvent: model.ClusterEventNone, + }) + + lc.doClearCacheCluster(c) + assert.Len(t, cluster.GetMessages(), 1) +}