snapshot of https://github.com/mattermost/mattermost.git (master, 2026-09-16; blobs > 131072B omitted)
Some checks failed
Server CI / Postgres (shard 0) (push) Has been skipped
Server CI / Postgres (shard 3) (push) Has been skipped
BuildEnv Docker Image / build-image (push) Failing after 4s
BuildEnv Docker Image / build-image-fips (push) Failing after 4s
Migration Review & Release Notes / Generate migration review & release notes (push) Failing after 3s
Server CI / Build Environment (push) Failing after 3s
Server CI / Postgres (shard 1) (push) Has been skipped
Tools CI / check-style (mattermost-govet) (push) Failing after 4s
Server CI / Postgres (shard 2) (push) Has been skipped
Tools CI / check-style (mmgotool) (push) Failing after 3s
Server CI / Elasticsearch v8 Compatibility (push) Has been skipped
Server CI / OpenSearch v2 Compatibility (push) Has been skipped
Server CI / Postgres FIPS (shard 0) (push) Has been skipped
Tools CI / Test (mattermost-govet) (push) Failing after 3s
Server CI / Postgres FIPS (shard 1) (push) Has been skipped
Server CI / Postgres FIPS (shard 2) (push) Has been skipped
Tools CI / Test (mmgotool) (push) Failing after 3s
Server CI / Postgres FIPS (shard 3) (push) Has been skipped
Server CI / Run mmctl tests (push) Has been skipped
Server CI / Run mmctl tests (FIPS) (push) Has been skipped
Server CI / Merge Postgres Test Results (push) Has been skipped
Server CI / Merge Postgres FIPS Test Results (push) Has been skipped
Server CI / Check backport migrations (push) Has been skipped
Server CI / Check generated files (push) Has been skipped
Server CI / check-style (push) Has been skipped
Server CI / Vet API (push) Has been skipped
Server CI / Build mattermost server app (push) Has been skipped
Server CI / Server CI Complete (push) Failing after 2s
Server CI / Server CI Artifacts (push) Has been skipped
Server CI / Sentry Upload (push) Has been skipped
Server CI / Server CI Report (push) Failing after 5m1s
Server CI Nightly Race / Race Detector (push) Has been skipped
CodeQL / Analyze (go) (push) Has been cancelled
CodeQL / Analyze (javascript) (push) Has been cancelled
Webapp CI Cache Warm / Warm Webapp node_modules Cache (push) Has been cancelled
E2E CI Cache Warm / Warm E2E npm Registry Cache (push) Has been cancelled
API / build (push) Has been cancelled
Web App CI / check-types (push) Has been cancelled
Web App CI / check-lint (push) Has been cancelled
Web App CI / check-i18n (push) Has been cancelled
Web App CI / check-external-links (push) Has been cancelled
Web App CI / test (platform) (push) Has been cancelled
Web App CI / test (mattermost-redux) (push) Has been cancelled
Web App CI / test (channels shard 1/4) (push) Has been cancelled
Web App CI / test (channels shard 2/4) (push) Has been cancelled
Web App CI / test (channels shard 3/4) (push) Has been cancelled
Web App CI / test (channels shard 4/4) (push) Has been cancelled
Web App CI / upload-coverage (push) Has been cancelled
Web App CI / build (push) Has been cancelled
YAML Lint / yamllint (push) Has been cancelled
Push mirrored docker images / cd/Push mirrored docker images (push) Has been cancelled
docs-cd / Build and deploy docs (push) Has been cancelled
Docs CI / build (push) Has been cancelled
E2E Cache Warm: Cypress deps / Warm Cypress deps cache (push) Has been cancelled
Scorecards supply-chain security / Scorecard analysis (push) Has been cancelled
Server CI Weekly / Postgres FIPS (push) Has been skipped
Server CI Weekly / Run mmctl tests (FIPS) (push) Has been skipped
Server CI Weekly / Postgres with binary parameters (push) Has been skipped
Server CI Weekly / Build Environment (push) Failing after 1s
Server CI Cache Warm / Warm Go Module and Build Cache (push) Failing after 1s
Server CI Nightly Race / Build Environment (push) Failing after 1s
Some checks failed
Server CI / Postgres (shard 0) (push) Has been skipped
Server CI / Postgres (shard 3) (push) Has been skipped
BuildEnv Docker Image / build-image (push) Failing after 4s
BuildEnv Docker Image / build-image-fips (push) Failing after 4s
Migration Review & Release Notes / Generate migration review & release notes (push) Failing after 3s
Server CI / Build Environment (push) Failing after 3s
Server CI / Postgres (shard 1) (push) Has been skipped
Tools CI / check-style (mattermost-govet) (push) Failing after 4s
Server CI / Postgres (shard 2) (push) Has been skipped
Tools CI / check-style (mmgotool) (push) Failing after 3s
Server CI / Elasticsearch v8 Compatibility (push) Has been skipped
Server CI / OpenSearch v2 Compatibility (push) Has been skipped
Server CI / Postgres FIPS (shard 0) (push) Has been skipped
Tools CI / Test (mattermost-govet) (push) Failing after 3s
Server CI / Postgres FIPS (shard 1) (push) Has been skipped
Server CI / Postgres FIPS (shard 2) (push) Has been skipped
Tools CI / Test (mmgotool) (push) Failing after 3s
Server CI / Postgres FIPS (shard 3) (push) Has been skipped
Server CI / Run mmctl tests (push) Has been skipped
Server CI / Run mmctl tests (FIPS) (push) Has been skipped
Server CI / Merge Postgres Test Results (push) Has been skipped
Server CI / Merge Postgres FIPS Test Results (push) Has been skipped
Server CI / Check backport migrations (push) Has been skipped
Server CI / Check generated files (push) Has been skipped
Server CI / check-style (push) Has been skipped
Server CI / Vet API (push) Has been skipped
Server CI / Build mattermost server app (push) Has been skipped
Server CI / Server CI Complete (push) Failing after 2s
Server CI / Server CI Artifacts (push) Has been skipped
Server CI / Sentry Upload (push) Has been skipped
Server CI / Server CI Report (push) Failing after 5m1s
Server CI Nightly Race / Race Detector (push) Has been skipped
CodeQL / Analyze (go) (push) Has been cancelled
CodeQL / Analyze (javascript) (push) Has been cancelled
Webapp CI Cache Warm / Warm Webapp node_modules Cache (push) Has been cancelled
E2E CI Cache Warm / Warm E2E npm Registry Cache (push) Has been cancelled
API / build (push) Has been cancelled
Web App CI / check-types (push) Has been cancelled
Web App CI / check-lint (push) Has been cancelled
Web App CI / check-i18n (push) Has been cancelled
Web App CI / check-external-links (push) Has been cancelled
Web App CI / test (platform) (push) Has been cancelled
Web App CI / test (mattermost-redux) (push) Has been cancelled
Web App CI / test (channels shard 1/4) (push) Has been cancelled
Web App CI / test (channels shard 2/4) (push) Has been cancelled
Web App CI / test (channels shard 3/4) (push) Has been cancelled
Web App CI / test (channels shard 4/4) (push) Has been cancelled
Web App CI / upload-coverage (push) Has been cancelled
Web App CI / build (push) Has been cancelled
YAML Lint / yamllint (push) Has been cancelled
Push mirrored docker images / cd/Push mirrored docker images (push) Has been cancelled
docs-cd / Build and deploy docs (push) Has been cancelled
Docs CI / build (push) Has been cancelled
E2E Cache Warm: Cypress deps / Warm Cypress deps cache (push) Has been cancelled
Scorecards supply-chain security / Scorecard analysis (push) Has been cancelled
Server CI Weekly / Postgres FIPS (push) Has been skipped
Server CI Weekly / Run mmctl tests (FIPS) (push) Has been skipped
Server CI Weekly / Postgres with binary parameters (push) Has been skipped
Server CI Weekly / Build Environment (push) Failing after 1s
Server CI Cache Warm / Warm Go Module and Build Cache (push) Failing after 1s
Server CI Nightly Race / Build Environment (push) Failing after 1s
This commit is contained in:
836
server/channels/store/localcachelayer/layer.go
Normal file
836
server/channels/store/localcachelayer/layer.go
Normal file
@@ -0,0 +1,836 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package localcachelayer
|
||||
|
||||
import (
|
||||
"runtime"
|
||||
"time"
|
||||
|
||||
lru "github.com/hashicorp/golang-lru/v2"
|
||||
|
||||
"github.com/mattermost/mattermost/server/public/model"
|
||||
"github.com/mattermost/mattermost/server/public/shared/mlog"
|
||||
"github.com/mattermost/mattermost/server/v8/channels/store"
|
||||
"github.com/mattermost/mattermost/server/v8/einterfaces"
|
||||
"github.com/mattermost/mattermost/server/v8/platform/services/cache"
|
||||
)
|
||||
|
||||
const (
|
||||
ReactionCacheSize = 20000
|
||||
ReactionCacheSec = 30 * 60
|
||||
|
||||
RoleCacheSize = 20000
|
||||
RoleCacheSec = 30 * 60
|
||||
|
||||
SchemeCacheSize = 20000
|
||||
SchemeCacheSec = 30 * 60
|
||||
|
||||
FileInfoCacheSize = 25000
|
||||
FileInfoCacheSec = 30 * 60
|
||||
|
||||
ChannelGuestCountCacheSize = model.ChannelCacheSize
|
||||
ChannelGuestCountCacheSec = 30 * 60
|
||||
|
||||
WebhookCacheSize = 25000
|
||||
WebhookCacheSec = 15 * 60
|
||||
|
||||
EmojiCacheSize = 5000
|
||||
EmojiCacheSec = 30 * 60
|
||||
// Kept short so that a lost cluster invalidation or a stale replica read
|
||||
// cannot hide a newly created emoji for longer than this.
|
||||
EmojiNotFoundCacheSec = 60
|
||||
|
||||
ChannelPinnedPostsCountsCacheSize = model.ChannelCacheSize
|
||||
ChannelPinnedPostsCountsCacheSec = 30 * 60
|
||||
AllChannelMembersForUserCacheSize = model.SessionCacheSize
|
||||
AllChannelMembersForUserCacheDuration = 15 * time.Minute
|
||||
|
||||
AllChannelMembersNotifyPropsForChannelCacheSize = model.SessionCacheSize
|
||||
AllChannelMembersNotifyPropsForChannelCacheDuration = 30 * time.Minute
|
||||
|
||||
ChannelCacheDuration = 15 * time.Minute
|
||||
|
||||
ChannelMembersCountsCacheSize = model.ChannelCacheSize
|
||||
ChannelMembersCountsCacheSec = 30 * 60
|
||||
|
||||
LastPostsCacheSize = 20000
|
||||
LastPostsCacheSec = 30 * 60
|
||||
PostsUsageCacheSize = 1
|
||||
PostsUsageCacheSec = 30 * 60
|
||||
|
||||
TermsOfServiceCacheSize = 20000
|
||||
TermsOfServiceCacheSec = 30 * 60
|
||||
LastPostTimeCacheSize = 25000
|
||||
LastPostTimeCacheSec = 15 * 60
|
||||
|
||||
UserProfileByIDCacheSize = 20000
|
||||
UserProfileByIDSec = 30 * 60
|
||||
|
||||
ProfilesInChannelCacheSize = model.ChannelCacheSize
|
||||
ProfilesInChannelCacheSec = 15 * 60
|
||||
|
||||
TeamCacheSize = 20000
|
||||
TeamCacheSec = 30 * 60
|
||||
|
||||
ChannelCacheSec = 15 * 60 // 15 mins
|
||||
|
||||
// Auto-translation caches
|
||||
UserAutoTranslationCacheSize = 50000 // User+channel combos
|
||||
UserAutoTranslationCacheSec = 15 * 60
|
||||
PostTranslationEtagCacheSize = 25000 // Channel etags for post translations
|
||||
PostTranslationEtagCacheSec = 15 * 60
|
||||
|
||||
ContentFlaggingCacheSize = 100
|
||||
|
||||
DeliveryTrackingCacheSize = 100
|
||||
|
||||
DeliveryTrackingChannelCacheSize = 20000
|
||||
|
||||
ReadReceiptCacheSize = 50000
|
||||
|
||||
TemporaryPostCacheSize = 10000
|
||||
TemporaryPostCacheMinutes = 60
|
||||
|
||||
SessionAttributeCacheSize = model.SessionCacheSize
|
||||
|
||||
PropertyFieldCacheSize = 100
|
||||
PropertyFieldCacheSec = 30 * 60
|
||||
|
||||
AccessControlPolicyEtagCacheSize = 25000 // Per-channel render-ETag epochs
|
||||
AccessControlPolicyEtagCacheSec = 15 * 60
|
||||
|
||||
UserPropertyValuesEpochCacheSize = 25000 // Per-user CPA epochs
|
||||
UserPropertyValuesEpochCacheSec = 15 * 60
|
||||
)
|
||||
|
||||
var clearCacheMessageData = []byte("")
|
||||
|
||||
type LocalCacheStore struct {
|
||||
store.Store
|
||||
cacheType string
|
||||
metrics einterfaces.MetricsInterface
|
||||
cluster einterfaces.ClusterInterface
|
||||
logger mlog.LoggerIFace
|
||||
|
||||
reaction LocalCacheReactionStore
|
||||
reactionCache cache.Cache
|
||||
|
||||
fileInfo LocalCacheFileInfoStore
|
||||
fileInfoCache cache.Cache
|
||||
|
||||
role LocalCacheRoleStore
|
||||
roleCache cache.Cache
|
||||
rolePermissionsCache 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
|
||||
channelMembersForUserCache cache.Cache
|
||||
channelMembersNotifyPropsCache cache.Cache
|
||||
channelByNameCache cache.Cache
|
||||
|
||||
webhook LocalCacheWebhookStore
|
||||
webhookCache cache.Cache
|
||||
|
||||
post LocalCachePostStore
|
||||
postLastPostsCache cache.Cache
|
||||
lastPostTimeCache cache.Cache
|
||||
postsUsageCache cache.Cache
|
||||
|
||||
user *LocalCacheUserStore
|
||||
allUserCache cache.Cache
|
||||
userProfileByIdsCache cache.Cache
|
||||
profilesInChannelCache cache.Cache
|
||||
|
||||
team LocalCacheTeamStore
|
||||
teamAllTeamIdsForUserCache cache.Cache
|
||||
|
||||
termsOfService LocalCacheTermsOfServiceStore
|
||||
termsOfServiceCache cache.Cache
|
||||
|
||||
autotranslation LocalCacheAutoTranslationStore
|
||||
userAutoTranslationCache cache.Cache
|
||||
postTranslationEtagCache cache.Cache
|
||||
|
||||
contentFlagging LocalCacheContentFlaggingStore
|
||||
contentFlaggingCache cache.Cache
|
||||
|
||||
deliveryTracking *LocalCacheDeliveryTrackingStore
|
||||
deliveryTrackingCache cache.Cache
|
||||
|
||||
readReceipt LocalCacheReadReceiptStore
|
||||
readReceiptCache cache.Cache
|
||||
readReceiptPostReadersCache cache.Cache
|
||||
readReceiptPostUnreadCountCache cache.Cache
|
||||
|
||||
temporaryPost LocalCacheTemporaryPostStore
|
||||
temporaryPostCache cache.Cache
|
||||
|
||||
sessionAttribute LocalCacheSessionAttributeStore
|
||||
sessionAttributeCache cache.Cache
|
||||
|
||||
propertyField LocalCachePropertyFieldStore
|
||||
propertyFieldCache cache.Cache
|
||||
|
||||
accessControlPolicy LocalCacheAccessControlPolicyStore
|
||||
accessControlPolicyEtagCache cache.Cache
|
||||
|
||||
attributes LocalCacheAttributesStore
|
||||
userPropertyValuesEpochCache cache.Cache
|
||||
}
|
||||
|
||||
func NewLocalCacheLayer(baseStore store.Store, metrics einterfaces.MetricsInterface, cluster einterfaces.ClusterInterface, cacheProvider cache.Provider, logger mlog.LoggerIFace) (localCacheStore LocalCacheStore, err error) {
|
||||
localCacheStore = LocalCacheStore{
|
||||
Store: baseStore,
|
||||
cluster: cluster,
|
||||
metrics: metrics,
|
||||
cacheType: cacheProvider.Type(),
|
||||
logger: logger,
|
||||
}
|
||||
// Reactions
|
||||
if localCacheStore.reactionCache, err = cacheProvider.NewCache(&cache.CacheOptions{
|
||||
Size: ReactionCacheSize,
|
||||
Name: "Reaction",
|
||||
DefaultExpiry: ReactionCacheSec * time.Second,
|
||||
InvalidateClusterEvent: model.ClusterEventInvalidateCacheForReactions,
|
||||
}); err != nil {
|
||||
return
|
||||
}
|
||||
localCacheStore.reaction = LocalCacheReactionStore{ReactionStore: baseStore.Reaction(), rootStore: &localCacheStore}
|
||||
|
||||
// Roles
|
||||
if localCacheStore.roleCache, err = cacheProvider.NewCache(&cache.CacheOptions{
|
||||
Size: RoleCacheSize,
|
||||
Name: "Role",
|
||||
DefaultExpiry: RoleCacheSec * time.Second,
|
||||
InvalidateClusterEvent: model.ClusterEventInvalidateCacheForRoles,
|
||||
Striped: true,
|
||||
StripedBuckets: max(runtime.NumCPU()-1, 1),
|
||||
}); err != nil {
|
||||
return
|
||||
}
|
||||
if localCacheStore.rolePermissionsCache, err = cacheProvider.NewCache(&cache.CacheOptions{
|
||||
Size: RoleCacheSize,
|
||||
Name: "RolePermission",
|
||||
DefaultExpiry: RoleCacheSec * time.Second,
|
||||
InvalidateClusterEvent: model.ClusterEventInvalidateCacheForRolePermissions,
|
||||
}); err != nil {
|
||||
return
|
||||
}
|
||||
localCacheStore.role = LocalCacheRoleStore{RoleStore: baseStore.Role(), rootStore: &localCacheStore}
|
||||
|
||||
// Schemes
|
||||
if localCacheStore.schemeCache, err = cacheProvider.NewCache(&cache.CacheOptions{
|
||||
Size: SchemeCacheSize,
|
||||
Name: "Scheme",
|
||||
DefaultExpiry: SchemeCacheSec * time.Second,
|
||||
InvalidateClusterEvent: model.ClusterEventInvalidateCacheForSchemes,
|
||||
}); err != nil {
|
||||
return
|
||||
}
|
||||
localCacheStore.scheme = LocalCacheSchemeStore{SchemeStore: baseStore.Scheme(), rootStore: &localCacheStore}
|
||||
|
||||
// FileInfo
|
||||
if localCacheStore.fileInfoCache, err = cacheProvider.NewCache(&cache.CacheOptions{
|
||||
Size: FileInfoCacheSize,
|
||||
Name: "FileInfo",
|
||||
DefaultExpiry: FileInfoCacheSec * time.Second,
|
||||
InvalidateClusterEvent: model.ClusterEventInvalidateCacheForFileInfos,
|
||||
}); err != nil {
|
||||
return
|
||||
}
|
||||
localCacheStore.fileInfo = LocalCacheFileInfoStore{FileInfoStore: baseStore.FileInfo(), rootStore: &localCacheStore}
|
||||
|
||||
// Webhooks
|
||||
if localCacheStore.webhookCache, err = cacheProvider.NewCache(&cache.CacheOptions{
|
||||
Size: WebhookCacheSize,
|
||||
Name: "Webhook",
|
||||
DefaultExpiry: WebhookCacheSec * time.Second,
|
||||
InvalidateClusterEvent: model.ClusterEventInvalidateCacheForWebhooks,
|
||||
}); err != nil {
|
||||
return
|
||||
}
|
||||
localCacheStore.webhook = LocalCacheWebhookStore{WebhookStore: baseStore.Webhook(), rootStore: &localCacheStore}
|
||||
|
||||
// Emojis
|
||||
if localCacheStore.emojiCacheById, err = cacheProvider.NewCache(&cache.CacheOptions{
|
||||
Size: EmojiCacheSize,
|
||||
Name: "EmojiById",
|
||||
DefaultExpiry: EmojiCacheSec * time.Second,
|
||||
InvalidateClusterEvent: model.ClusterEventInvalidateCacheForEmojisById,
|
||||
}); err != nil {
|
||||
return
|
||||
}
|
||||
if localCacheStore.emojiIdCacheByName, err = cacheProvider.NewCache(&cache.CacheOptions{
|
||||
Size: EmojiCacheSize,
|
||||
Name: "EmojiByName",
|
||||
DefaultExpiry: EmojiCacheSec * time.Second,
|
||||
InvalidateClusterEvent: model.ClusterEventInvalidateCacheForEmojisIdByName,
|
||||
}); err != nil {
|
||||
return
|
||||
}
|
||||
localCacheStore.emoji = &LocalCacheEmojiStore{
|
||||
EmojiStore: baseStore.Emoji(),
|
||||
rootStore: &localCacheStore,
|
||||
emojiByIdInvalidations: make(map[string]bool),
|
||||
emojiByNameInvalidations: make(map[string]bool),
|
||||
}
|
||||
|
||||
// Channels
|
||||
if localCacheStore.channelPinnedPostCountsCache, err = cacheProvider.NewCache(&cache.CacheOptions{
|
||||
Size: ChannelPinnedPostsCountsCacheSize,
|
||||
Name: "ChannelPinnedPostsCounts",
|
||||
DefaultExpiry: ChannelPinnedPostsCountsCacheSec * time.Second,
|
||||
InvalidateClusterEvent: model.ClusterEventInvalidateCacheForChannelPinnedpostsCounts,
|
||||
}); err != nil {
|
||||
return
|
||||
}
|
||||
if localCacheStore.channelMemberCountsCache, err = cacheProvider.NewCache(&cache.CacheOptions{
|
||||
Size: ChannelMembersCountsCacheSize,
|
||||
Name: "ChannelMemberCounts",
|
||||
DefaultExpiry: ChannelMembersCountsCacheSec * time.Second,
|
||||
InvalidateClusterEvent: model.ClusterEventInvalidateCacheForChannelMemberCounts,
|
||||
}); err != nil {
|
||||
return
|
||||
}
|
||||
if localCacheStore.channelGuestCountCache, err = cacheProvider.NewCache(&cache.CacheOptions{
|
||||
Size: ChannelGuestCountCacheSize,
|
||||
Name: "ChannelGuestsCount",
|
||||
DefaultExpiry: ChannelGuestCountCacheSec * time.Second,
|
||||
InvalidateClusterEvent: model.ClusterEventInvalidateCacheForChannelGuestCount,
|
||||
}); err != nil {
|
||||
return
|
||||
}
|
||||
if localCacheStore.channelByIdCache, err = cacheProvider.NewCache(&cache.CacheOptions{
|
||||
Size: model.ChannelCacheSize,
|
||||
Name: "channelById",
|
||||
DefaultExpiry: ChannelCacheSec * time.Second,
|
||||
InvalidateClusterEvent: model.ClusterEventInvalidateCacheForChannel,
|
||||
}); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if localCacheStore.channelMembersForUserCache, err = cacheProvider.NewCache(&cache.CacheOptions{
|
||||
Size: AllChannelMembersForUserCacheSize,
|
||||
Name: "ChannelMembersForUser",
|
||||
DefaultExpiry: AllChannelMembersForUserCacheDuration,
|
||||
InvalidateClusterEvent: model.ClusterEventInvalidateCacheForUser,
|
||||
}); err != nil {
|
||||
return
|
||||
}
|
||||
if localCacheStore.channelMembersNotifyPropsCache, err = cacheProvider.NewCache(&cache.CacheOptions{
|
||||
Size: AllChannelMembersNotifyPropsForChannelCacheSize,
|
||||
Name: "ChannnelMembersNotifyProps",
|
||||
DefaultExpiry: AllChannelMembersNotifyPropsForChannelCacheDuration,
|
||||
InvalidateClusterEvent: model.ClusterEventInvalidateCacheForChannelMembersNotifyProps,
|
||||
}); err != nil {
|
||||
return
|
||||
}
|
||||
if localCacheStore.channelByNameCache, err = cacheProvider.NewCache(&cache.CacheOptions{
|
||||
Size: model.ChannelCacheSize,
|
||||
Name: "ChannelByName",
|
||||
DefaultExpiry: ChannelCacheDuration,
|
||||
InvalidateClusterEvent: model.ClusterEventInvalidateCacheForChannelByName,
|
||||
}); err != nil {
|
||||
return
|
||||
}
|
||||
localCacheStore.channel = LocalCacheChannelStore{ChannelStore: baseStore.Channel(), rootStore: &localCacheStore}
|
||||
|
||||
// Posts
|
||||
if localCacheStore.postLastPostsCache, err = cacheProvider.NewCache(&cache.CacheOptions{
|
||||
Size: LastPostsCacheSize,
|
||||
Name: "LastPost",
|
||||
DefaultExpiry: LastPostsCacheSec * time.Second,
|
||||
InvalidateClusterEvent: model.ClusterEventInvalidateCacheForLastPosts,
|
||||
}); err != nil {
|
||||
return
|
||||
}
|
||||
if localCacheStore.lastPostTimeCache, err = cacheProvider.NewCache(&cache.CacheOptions{
|
||||
Size: LastPostTimeCacheSize,
|
||||
Name: "LastPostTime",
|
||||
DefaultExpiry: LastPostTimeCacheSec * time.Second,
|
||||
InvalidateClusterEvent: model.ClusterEventInvalidateCacheForLastPostTime,
|
||||
}); err != nil {
|
||||
return
|
||||
}
|
||||
if localCacheStore.postsUsageCache, err = cacheProvider.NewCache(&cache.CacheOptions{
|
||||
Size: PostsUsageCacheSize,
|
||||
Name: "PostsUsage",
|
||||
DefaultExpiry: PostsUsageCacheSec * time.Second,
|
||||
InvalidateClusterEvent: model.ClusterEventInvalidateCacheForPostsUsage,
|
||||
}); err != nil {
|
||||
return
|
||||
}
|
||||
localCacheStore.post = LocalCachePostStore{PostStore: baseStore.Post(), rootStore: &localCacheStore}
|
||||
|
||||
// TOS
|
||||
if localCacheStore.termsOfServiceCache, err = cacheProvider.NewCache(&cache.CacheOptions{
|
||||
Size: TermsOfServiceCacheSize,
|
||||
Name: "TermsOfService",
|
||||
DefaultExpiry: TermsOfServiceCacheSec * time.Second,
|
||||
InvalidateClusterEvent: model.ClusterEventInvalidateCacheForTermsOfService,
|
||||
}); err != nil {
|
||||
return
|
||||
}
|
||||
localCacheStore.termsOfService = LocalCacheTermsOfServiceStore{TermsOfServiceStore: baseStore.TermsOfService(), rootStore: &localCacheStore}
|
||||
|
||||
// Users
|
||||
if localCacheStore.allUserCache, err = cacheProvider.NewCache(&cache.CacheOptions{
|
||||
Size: 1,
|
||||
Name: "AllUserProfiles",
|
||||
DefaultExpiry: UserProfileByIDSec * time.Second,
|
||||
InvalidateClusterEvent: model.ClusterEventInvalidateCacheForAllProfiles,
|
||||
}); err != nil {
|
||||
return
|
||||
}
|
||||
if localCacheStore.userProfileByIdsCache, err = cacheProvider.NewCache(&cache.CacheOptions{
|
||||
Size: UserProfileByIDCacheSize,
|
||||
Name: "UserProfileByIds",
|
||||
DefaultExpiry: UserProfileByIDSec * time.Second,
|
||||
InvalidateClusterEvent: model.ClusterEventInvalidateCacheForProfileByIds,
|
||||
Striped: true,
|
||||
StripedBuckets: max(runtime.NumCPU()-1, 1),
|
||||
}); err != nil {
|
||||
return
|
||||
}
|
||||
// Hardcoding this to LRU because of the volume of SCAN calls in case of Redis.
|
||||
if localCacheStore.profilesInChannelCache, err = cache.NewProvider().NewCache(&cache.CacheOptions{
|
||||
Size: ProfilesInChannelCacheSize,
|
||||
Name: "ProfilesInChannel",
|
||||
DefaultExpiry: ProfilesInChannelCacheSec * time.Second,
|
||||
InvalidateClusterEvent: model.ClusterEventInvalidateCacheForProfileInChannel,
|
||||
}); err != nil {
|
||||
return
|
||||
}
|
||||
localCacheStore.user = &LocalCacheUserStore{
|
||||
UserStore: baseStore.User(),
|
||||
rootStore: &localCacheStore,
|
||||
userProfileByIdsInvalidations: make(map[string]bool),
|
||||
}
|
||||
|
||||
// Teams
|
||||
if localCacheStore.teamAllTeamIdsForUserCache, err = cacheProvider.NewCache(&cache.CacheOptions{
|
||||
Size: TeamCacheSize,
|
||||
Name: "Team",
|
||||
DefaultExpiry: TeamCacheSec * time.Second,
|
||||
InvalidateClusterEvent: model.ClusterEventInvalidateCacheForTeams,
|
||||
}); err != nil {
|
||||
return
|
||||
}
|
||||
localCacheStore.team = LocalCacheTeamStore{TeamStore: baseStore.Team(), rootStore: &localCacheStore}
|
||||
|
||||
// Auto-translation
|
||||
if localCacheStore.userAutoTranslationCache, err = cacheProvider.NewCache(&cache.CacheOptions{
|
||||
Size: UserAutoTranslationCacheSize,
|
||||
Name: "UserAutoTranslation",
|
||||
DefaultExpiry: UserAutoTranslationCacheSec * time.Second,
|
||||
InvalidateClusterEvent: model.ClusterEventInvalidateCacheForUserAutoTranslation,
|
||||
}); err != nil {
|
||||
return
|
||||
}
|
||||
if localCacheStore.postTranslationEtagCache, err = cacheProvider.NewCache(&cache.CacheOptions{
|
||||
Size: PostTranslationEtagCacheSize,
|
||||
Name: "PostTranslationEtag",
|
||||
DefaultExpiry: PostTranslationEtagCacheSec * time.Second,
|
||||
InvalidateClusterEvent: model.ClusterEventInvalidateCacheForPostTranslationEtag,
|
||||
}); err != nil {
|
||||
return
|
||||
}
|
||||
localCacheStore.autotranslation = LocalCacheAutoTranslationStore{AutoTranslationStore: baseStore.AutoTranslation(), rootStore: &localCacheStore}
|
||||
if localCacheStore.contentFlaggingCache, err = cacheProvider.NewCache(&cache.CacheOptions{
|
||||
Size: ContentFlaggingCacheSize,
|
||||
Name: "ContentFlagging",
|
||||
InvalidateClusterEvent: model.ClusterEventInvalidateCacheForContentFlagging,
|
||||
}); err != nil {
|
||||
return
|
||||
}
|
||||
localCacheStore.contentFlagging = LocalCacheContentFlaggingStore{ContentFlaggingStore: baseStore.ContentFlagging(), rootStore: &localCacheStore}
|
||||
|
||||
if localCacheStore.deliveryTrackingCache, err = cacheProvider.NewCache(&cache.CacheOptions{
|
||||
Size: DeliveryTrackingCacheSize,
|
||||
Name: "DeliveryTracking",
|
||||
InvalidateClusterEvent: model.ClusterEventInvalidateCacheForDeliveryTracking,
|
||||
}); err != nil {
|
||||
return
|
||||
}
|
||||
var trackedChannels, trackableChannels *lru.Cache[string, bool]
|
||||
if trackedChannels, err = lru.New[string, bool](DeliveryTrackingChannelCacheSize); err != nil {
|
||||
return
|
||||
}
|
||||
if trackableChannels, err = lru.New[string, bool](DeliveryTrackingChannelCacheSize); err != nil {
|
||||
return
|
||||
}
|
||||
localCacheStore.deliveryTracking = &LocalCacheDeliveryTrackingStore{
|
||||
DeliveryTrackingStore: baseStore.DeliveryTracking(),
|
||||
rootStore: &localCacheStore,
|
||||
trackedChannels: trackedChannels,
|
||||
trackableChannels: trackableChannels,
|
||||
}
|
||||
|
||||
// Read Receipts
|
||||
if localCacheStore.readReceiptCache, err = cacheProvider.NewCache(&cache.CacheOptions{
|
||||
Size: ReadReceiptCacheSize,
|
||||
Name: "ReadReceipt",
|
||||
InvalidateClusterEvent: model.ClusterEventInvalidateCacheForReadReceipts,
|
||||
}); err != nil {
|
||||
return
|
||||
}
|
||||
if localCacheStore.readReceiptPostReadersCache, err = cacheProvider.NewCache(&cache.CacheOptions{
|
||||
Size: ReadReceiptCacheSize,
|
||||
Name: "ReadReceiptPostReaders",
|
||||
InvalidateClusterEvent: model.ClusterEventInvalidateCacheForReadReceipts,
|
||||
}); err != nil {
|
||||
return
|
||||
}
|
||||
if localCacheStore.readReceiptPostUnreadCountCache, err = cacheProvider.NewCache(&cache.CacheOptions{
|
||||
Size: ReadReceiptCacheSize,
|
||||
Name: "ReadReceiptPostUnreadCount",
|
||||
InvalidateClusterEvent: model.ClusterEventInvalidateCacheForReadReceipts,
|
||||
}); err != nil {
|
||||
return
|
||||
}
|
||||
localCacheStore.readReceipt = LocalCacheReadReceiptStore{ReadReceiptStore: baseStore.ReadReceipt(), rootStore: &localCacheStore}
|
||||
|
||||
// Temporary Posts
|
||||
if localCacheStore.temporaryPostCache, err = cacheProvider.NewCache(&cache.CacheOptions{
|
||||
Size: TemporaryPostCacheSize,
|
||||
Name: "TemporaryPost",
|
||||
DefaultExpiry: TemporaryPostCacheMinutes * time.Minute,
|
||||
InvalidateClusterEvent: model.ClusterEventInvalidateCacheForTemporaryPosts,
|
||||
}); err != nil {
|
||||
return
|
||||
}
|
||||
localCacheStore.temporaryPost = LocalCacheTemporaryPostStore{TemporaryPostStore: baseStore.TemporaryPost(), rootStore: &localCacheStore}
|
||||
|
||||
// Session Attributes
|
||||
if localCacheStore.sessionAttributeCache, err = cacheProvider.NewCache(&cache.CacheOptions{
|
||||
Size: SessionAttributeCacheSize,
|
||||
Name: "SessionAttribute",
|
||||
InvalidateClusterEvent: model.ClusterEventInvalidateCacheForSessionAttributes,
|
||||
}); err != nil {
|
||||
return
|
||||
}
|
||||
localCacheStore.sessionAttribute = LocalCacheSessionAttributeStore{SessionAttributeStore: baseStore.SessionAttribute(), rootStore: &localCacheStore}
|
||||
|
||||
// Property Fields
|
||||
if localCacheStore.propertyFieldCache, err = cacheProvider.NewCache(&cache.CacheOptions{
|
||||
Size: PropertyFieldCacheSize,
|
||||
Name: "PropertyField",
|
||||
DefaultExpiry: PropertyFieldCacheSec * time.Second,
|
||||
InvalidateClusterEvent: model.ClusterEventInvalidateCacheForPropertyFields,
|
||||
}); err != nil {
|
||||
return
|
||||
}
|
||||
localCacheStore.propertyField = LocalCachePropertyFieldStore{PropertyFieldStore: baseStore.PropertyField(), rootStore: &localCacheStore}
|
||||
|
||||
// Access Control Policy render-ETag epochs
|
||||
if localCacheStore.accessControlPolicyEtagCache, err = cacheProvider.NewCache(&cache.CacheOptions{
|
||||
Size: AccessControlPolicyEtagCacheSize,
|
||||
Name: "AccessControlPolicyEtag",
|
||||
DefaultExpiry: AccessControlPolicyEtagCacheSec * time.Second,
|
||||
InvalidateClusterEvent: model.ClusterEventInvalidateCacheForAccessControlPolicyEtag,
|
||||
}); err != nil {
|
||||
return
|
||||
}
|
||||
localCacheStore.accessControlPolicy = LocalCacheAccessControlPolicyStore{AccessControlPolicyStore: baseStore.AccessControlPolicy(), rootStore: &localCacheStore}
|
||||
|
||||
// User property-values (CPA) epochs
|
||||
if localCacheStore.userPropertyValuesEpochCache, err = cacheProvider.NewCache(&cache.CacheOptions{
|
||||
Size: UserPropertyValuesEpochCacheSize,
|
||||
Name: "UserPropertyValuesEpoch",
|
||||
DefaultExpiry: UserPropertyValuesEpochCacheSec * time.Second,
|
||||
InvalidateClusterEvent: model.ClusterEventInvalidateCacheForUserPropertyValuesEpoch,
|
||||
}); err != nil {
|
||||
return
|
||||
}
|
||||
localCacheStore.attributes = LocalCacheAttributesStore{AttributesStore: baseStore.Attributes(), rootStore: &localCacheStore}
|
||||
|
||||
if cluster != nil {
|
||||
cluster.RegisterClusterMessageHandler(model.ClusterEventInvalidateCacheForReactions, localCacheStore.reaction.handleClusterInvalidateReaction)
|
||||
cluster.RegisterClusterMessageHandler(model.ClusterEventInvalidateCacheForRoles, localCacheStore.role.handleClusterInvalidateRole)
|
||||
cluster.RegisterClusterMessageHandler(model.ClusterEventInvalidateCacheForRolePermissions, localCacheStore.role.handleClusterInvalidateRolePermissions)
|
||||
cluster.RegisterClusterMessageHandler(model.ClusterEventInvalidateCacheForSchemes, localCacheStore.scheme.handleClusterInvalidateScheme)
|
||||
cluster.RegisterClusterMessageHandler(model.ClusterEventInvalidateCacheForFileInfos, localCacheStore.fileInfo.handleClusterInvalidateFileInfo)
|
||||
cluster.RegisterClusterMessageHandler(model.ClusterEventInvalidateCacheForLastPostTime, localCacheStore.post.handleClusterInvalidateLastPostTime)
|
||||
cluster.RegisterClusterMessageHandler(model.ClusterEventInvalidateCacheForPostsUsage, localCacheStore.post.handleClusterInvalidatePostsUsage)
|
||||
cluster.RegisterClusterMessageHandler(model.ClusterEventInvalidateCacheForWebhooks, localCacheStore.webhook.handleClusterInvalidateWebhook)
|
||||
cluster.RegisterClusterMessageHandler(model.ClusterEventInvalidateCacheForEmojisById, localCacheStore.emoji.handleClusterInvalidateEmojiById)
|
||||
cluster.RegisterClusterMessageHandler(model.ClusterEventInvalidateCacheForEmojisIdByName, localCacheStore.emoji.handleClusterInvalidateEmojiIdByName)
|
||||
cluster.RegisterClusterMessageHandler(model.ClusterEventInvalidateCacheForChannelPinnedpostsCounts, localCacheStore.channel.handleClusterInvalidateChannelPinnedPostCount)
|
||||
cluster.RegisterClusterMessageHandler(model.ClusterEventInvalidateCacheForChannelMemberCounts, localCacheStore.channel.handleClusterInvalidateChannelMemberCounts)
|
||||
cluster.RegisterClusterMessageHandler(model.ClusterEventInvalidateCacheForChannelGuestCount, localCacheStore.channel.handleClusterInvalidateChannelGuestCounts)
|
||||
cluster.RegisterClusterMessageHandler(model.ClusterEventInvalidateCacheForChannel, localCacheStore.channel.handleClusterInvalidateChannelById)
|
||||
cluster.RegisterClusterMessageHandler(model.ClusterEventInvalidateCacheForUser, localCacheStore.channel.handleClusterInvalidateChannelForUser)
|
||||
cluster.RegisterClusterMessageHandler(model.ClusterEventInvalidateCacheForChannelMembersNotifyProps, localCacheStore.channel.handleClusterInvalidateChannelMembersNotifyProps)
|
||||
cluster.RegisterClusterMessageHandler(model.ClusterEventInvalidateCacheForChannelByName, localCacheStore.channel.handleClusterInvalidateChannelByName)
|
||||
cluster.RegisterClusterMessageHandler(model.ClusterEventInvalidateCacheForLastPosts, localCacheStore.post.handleClusterInvalidateLastPosts)
|
||||
cluster.RegisterClusterMessageHandler(model.ClusterEventInvalidateCacheForTermsOfService, localCacheStore.termsOfService.handleClusterInvalidateTermsOfService)
|
||||
cluster.RegisterClusterMessageHandler(model.ClusterEventInvalidateCacheForProfileByIds, localCacheStore.user.handleClusterInvalidateScheme)
|
||||
cluster.RegisterClusterMessageHandler(model.ClusterEventInvalidateCacheForProfileInChannel, localCacheStore.user.handleClusterInvalidateProfilesInChannel)
|
||||
cluster.RegisterClusterMessageHandler(model.ClusterEventInvalidateCacheForAllProfiles, localCacheStore.user.handleClusterInvalidateAllProfiles)
|
||||
cluster.RegisterClusterMessageHandler(model.ClusterEventInvalidateCacheForTeams, localCacheStore.team.handleClusterInvalidateTeam)
|
||||
cluster.RegisterClusterMessageHandler(model.ClusterEventInvalidateCacheForUserAutoTranslation, localCacheStore.autotranslation.handleClusterInvalidateUserAutoTranslation)
|
||||
cluster.RegisterClusterMessageHandler(model.ClusterEventInvalidateCacheForPostTranslationEtag, localCacheStore.autotranslation.handleClusterInvalidatePostTranslationEtag)
|
||||
cluster.RegisterClusterMessageHandler(model.ClusterEventInvalidateCacheForContentFlagging, localCacheStore.contentFlagging.handleClusterInvalidateContentFlagging)
|
||||
cluster.RegisterClusterMessageHandler(model.ClusterEventInvalidateCacheForDeliveryTracking, localCacheStore.deliveryTracking.handleClusterInvalidateDeliveryTracking)
|
||||
cluster.RegisterClusterMessageHandler(model.ClusterEventInvalidateCacheForReadReceipts, localCacheStore.readReceipt.handleClusterInvalidateReadReceipts)
|
||||
cluster.RegisterClusterMessageHandler(model.ClusterEventInvalidateCacheForTemporaryPosts, localCacheStore.temporaryPost.handleClusterInvalidateTemporaryPosts)
|
||||
cluster.RegisterClusterMessageHandler(model.ClusterEventInvalidateCacheForSessionAttributes, localCacheStore.sessionAttribute.handleClusterInvalidateSessionAttributes)
|
||||
cluster.RegisterClusterMessageHandler(model.ClusterEventInvalidateCacheForPropertyFields, localCacheStore.propertyField.handleClusterInvalidatePropertyField)
|
||||
cluster.RegisterClusterMessageHandler(model.ClusterEventInvalidateCacheForAccessControlPolicyEtag, localCacheStore.accessControlPolicy.handleClusterInvalidateAccessControlPolicyEtag)
|
||||
cluster.RegisterClusterMessageHandler(model.ClusterEventInvalidateCacheForUserPropertyValuesEpoch, localCacheStore.attributes.handleClusterInvalidateUserPropertyValuesEpoch)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (s LocalCacheStore) Reaction() store.ReactionStore {
|
||||
return s.reaction
|
||||
}
|
||||
|
||||
func (s LocalCacheStore) Role() store.RoleStore {
|
||||
return s.role
|
||||
}
|
||||
|
||||
func (s LocalCacheStore) Scheme() store.SchemeStore {
|
||||
return s.scheme
|
||||
}
|
||||
|
||||
func (s LocalCacheStore) FileInfo() store.FileInfoStore {
|
||||
return s.fileInfo
|
||||
}
|
||||
|
||||
func (s LocalCacheStore) Webhook() store.WebhookStore {
|
||||
return s.webhook
|
||||
}
|
||||
|
||||
func (s LocalCacheStore) Emoji() store.EmojiStore {
|
||||
return s.emoji
|
||||
}
|
||||
|
||||
func (s LocalCacheStore) Channel() store.ChannelStore {
|
||||
return s.channel
|
||||
}
|
||||
|
||||
func (s LocalCacheStore) Post() store.PostStore {
|
||||
return s.post
|
||||
}
|
||||
|
||||
func (s LocalCacheStore) TermsOfService() store.TermsOfServiceStore {
|
||||
return s.termsOfService
|
||||
}
|
||||
|
||||
func (s LocalCacheStore) User() store.UserStore {
|
||||
return s.user
|
||||
}
|
||||
|
||||
func (s LocalCacheStore) Team() store.TeamStore {
|
||||
return s.team
|
||||
}
|
||||
|
||||
func (s LocalCacheStore) AutoTranslation() store.AutoTranslationStore {
|
||||
return s.autotranslation
|
||||
}
|
||||
|
||||
func (s LocalCacheStore) ContentFlagging() store.ContentFlaggingStore {
|
||||
return s.contentFlagging
|
||||
}
|
||||
|
||||
func (s LocalCacheStore) DeliveryTracking() store.DeliveryTrackingStore {
|
||||
return s.deliveryTracking
|
||||
}
|
||||
|
||||
func (s LocalCacheStore) ReadReceipt() store.ReadReceiptStore {
|
||||
return s.readReceipt
|
||||
}
|
||||
|
||||
func (s LocalCacheStore) TemporaryPost() store.TemporaryPostStore {
|
||||
return s.temporaryPost
|
||||
}
|
||||
|
||||
func (s LocalCacheStore) SessionAttribute() store.SessionAttributeStore {
|
||||
return &s.sessionAttribute
|
||||
}
|
||||
|
||||
func (s LocalCacheStore) PropertyField() store.PropertyFieldStore {
|
||||
return s.propertyField
|
||||
}
|
||||
|
||||
func (s LocalCacheStore) AccessControlPolicy() store.AccessControlPolicyStore {
|
||||
return s.accessControlPolicy
|
||||
}
|
||||
|
||||
func (s LocalCacheStore) Attributes() store.AttributesStore {
|
||||
return s.attributes
|
||||
}
|
||||
|
||||
func (s LocalCacheStore) DropAllTables() {
|
||||
s.Invalidate()
|
||||
s.Store.DropAllTables()
|
||||
}
|
||||
|
||||
func (s *LocalCacheStore) doInvalidateCacheCluster(cache cache.Cache, key string, props map[string]string) {
|
||||
err := cache.Remove(key)
|
||||
if err != nil {
|
||||
s.logger.Warn("Error while removing cache entry", mlog.Err(err), mlog.String("cache_name", cache.Name()))
|
||||
}
|
||||
if s.cluster != nil && cache.GetInvalidateClusterEvent() != model.ClusterEventNone {
|
||||
msg := &model.ClusterMessage{
|
||||
Event: cache.GetInvalidateClusterEvent(),
|
||||
SendType: model.ClusterSendBestEffort,
|
||||
Data: []byte(key),
|
||||
}
|
||||
if props != nil {
|
||||
msg.Props = props
|
||||
}
|
||||
s.cluster.SendClusterMessage(msg)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *LocalCacheStore) doMultiInvalidateCacheCluster(cache cache.Cache, keys []string, props map[string]string) {
|
||||
err := cache.RemoveMulti(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 && cache.GetInvalidateClusterEvent() != model.ClusterEventNone {
|
||||
for _, key := range keys {
|
||||
msg := &model.ClusterMessage{
|
||||
Event: cache.GetInvalidateClusterEvent(),
|
||||
SendType: model.ClusterSendBestEffort,
|
||||
Data: []byte(key),
|
||||
}
|
||||
if props != nil {
|
||||
msg.Props = props
|
||||
}
|
||||
s.cluster.SendClusterMessage(msg)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s *LocalCacheStore) doStandardAddToCache(cache cache.Cache, key string, value any) {
|
||||
err := cache.SetWithDefaultExpiry(key, value)
|
||||
if err != nil {
|
||||
s.logger.Warn("Error while setting cache entry", mlog.Err(err), mlog.String("cache_name", cache.Name()))
|
||||
}
|
||||
}
|
||||
|
||||
func (s *LocalCacheStore) doStandardAddToCacheWithExpiry(cache cache.Cache, key string, value any, ttl time.Duration) {
|
||||
err := cache.SetWithExpiry(key, value, ttl)
|
||||
if err != nil {
|
||||
s.logger.Warn("Error while setting cache entry", mlog.Err(err), mlog.String("cache_name", cache.Name()))
|
||||
}
|
||||
}
|
||||
|
||||
func (s *LocalCacheStore) doStandardReadCache(c cache.Cache, key string, value any) error {
|
||||
err := c.Get(key, value)
|
||||
if err == nil {
|
||||
if s.metrics != nil {
|
||||
s.metrics.IncrementMemCacheHitCounter(c.Name())
|
||||
}
|
||||
return nil
|
||||
}
|
||||
if err != cache.ErrKeyNotFound {
|
||||
s.logger.Warn("Error while reading from cache", mlog.Err(err), mlog.String("cache_name", c.Name()))
|
||||
}
|
||||
if s.metrics != nil {
|
||||
s.metrics.IncrementMemCacheMissCounter(c.Name())
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (s *LocalCacheStore) doMultiReadCache(cache cache.Cache, keys []string, values []any) []error {
|
||||
errs := cache.GetMulti(keys, values)
|
||||
if s.metrics != nil {
|
||||
for _, err := range errs {
|
||||
if err == nil {
|
||||
s.metrics.IncrementMemCacheHitCounter(cache.Name())
|
||||
continue
|
||||
}
|
||||
s.metrics.IncrementMemCacheMissCounter(cache.Name())
|
||||
}
|
||||
}
|
||||
return errs
|
||||
}
|
||||
|
||||
func (s *LocalCacheStore) doIncrementCache(cache cache.ExternalCache, key string, val int) {
|
||||
err := cache.Increment(key, val)
|
||||
if err != nil {
|
||||
s.logger.Warn("Error while incrementing cache entry", mlog.Err(err), mlog.String("cache_name", cache.Name()))
|
||||
}
|
||||
}
|
||||
|
||||
func (s *LocalCacheStore) doDecrementCache(cache cache.ExternalCache, key string, val int) {
|
||||
err := cache.Decrement(key, val)
|
||||
if err != nil {
|
||||
s.logger.Warn("Error while decrementing cache entry", mlog.Err(err), mlog.String("cache_name", cache.Name()))
|
||||
}
|
||||
}
|
||||
|
||||
func (s *LocalCacheStore) doClearCacheCluster(cache cache.Cache) {
|
||||
err := cache.Purge()
|
||||
if err != nil {
|
||||
s.logger.Warn("Error while purging cache", mlog.Err(err), mlog.String("cache_name", cache.Name()))
|
||||
}
|
||||
if s.cluster != nil && cache.GetInvalidateClusterEvent() != model.ClusterEventNone {
|
||||
msg := &model.ClusterMessage{
|
||||
Event: cache.GetInvalidateClusterEvent(),
|
||||
SendType: model.ClusterSendBestEffort,
|
||||
Data: clearCacheMessageData,
|
||||
}
|
||||
s.cluster.SendClusterMessage(msg)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *LocalCacheStore) Invalidate() {
|
||||
s.doClearCacheCluster(s.reactionCache)
|
||||
s.doClearCacheCluster(s.schemeCache)
|
||||
s.doClearCacheCluster(s.roleCache)
|
||||
s.doClearCacheCluster(s.fileInfoCache)
|
||||
s.doClearCacheCluster(s.webhookCache)
|
||||
s.doClearCacheCluster(s.emojiCacheById)
|
||||
s.doClearCacheCluster(s.emojiIdCacheByName)
|
||||
s.doClearCacheCluster(s.channelMemberCountsCache)
|
||||
s.doClearCacheCluster(s.channelPinnedPostCountsCache)
|
||||
s.doClearCacheCluster(s.channelGuestCountCache)
|
||||
s.doClearCacheCluster(s.channelByIdCache)
|
||||
s.doClearCacheCluster(s.channelMembersForUserCache)
|
||||
s.doClearCacheCluster(s.channelMembersNotifyPropsCache)
|
||||
s.doClearCacheCluster(s.channelByNameCache)
|
||||
s.doClearCacheCluster(s.postLastPostsCache)
|
||||
s.doClearCacheCluster(s.termsOfServiceCache)
|
||||
s.doClearCacheCluster(s.lastPostTimeCache)
|
||||
s.doClearCacheCluster(s.userProfileByIdsCache)
|
||||
s.doClearCacheCluster(s.allUserCache)
|
||||
s.doClearCacheCluster(s.profilesInChannelCache)
|
||||
s.doClearCacheCluster(s.teamAllTeamIdsForUserCache)
|
||||
s.doClearCacheCluster(s.rolePermissionsCache)
|
||||
s.doClearCacheCluster(s.userAutoTranslationCache)
|
||||
s.doClearCacheCluster(s.postTranslationEtagCache)
|
||||
s.doClearCacheCluster(s.deliveryTrackingCache)
|
||||
s.doClearCacheCluster(s.readReceiptCache)
|
||||
s.doClearCacheCluster(s.readReceiptPostReadersCache)
|
||||
s.doClearCacheCluster(s.temporaryPostCache)
|
||||
s.doClearCacheCluster(s.sessionAttributeCache)
|
||||
s.doClearCacheCluster(s.propertyFieldCache)
|
||||
s.doClearCacheCluster(s.accessControlPolicyEtagCache)
|
||||
s.doClearCacheCluster(s.userPropertyValuesEpochCache)
|
||||
}
|
||||
|
||||
// allocateCacheTargets is used to fill target value types
|
||||
// for getting items from cache.
|
||||
func allocateCacheTargets[T any](l int) []any {
|
||||
toPass := make([]any, 0, l)
|
||||
for range l {
|
||||
toPass = append(toPass, new(T))
|
||||
}
|
||||
return toPass
|
||||
}
|
||||
Reference in New Issue
Block a user