github.com/vnforks/kid/v5@v5.22.1-0.20200408055009-b89d99c65676/store/localcachelayer/layer.go (about)

     1  // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
     2  // See LICENSE.txt for license information.
     3  
     4  package localcachelayer
     5  
     6  import (
     7  	"github.com/vnforks/kid/v5/einterfaces"
     8  	"github.com/vnforks/kid/v5/model"
     9  	"github.com/vnforks/kid/v5/services/cache"
    10  	"github.com/vnforks/kid/v5/store"
    11  )
    12  
    13  const (
    14  	REACTION_CACHE_SIZE = 20000
    15  	REACTION_CACHE_SEC  = 30 * 60
    16  
    17  	ROLE_CACHE_SIZE = 20000
    18  	ROLE_CACHE_SEC  = 30 * 60
    19  
    20  	SCHEME_CACHE_SIZE = 20000
    21  	SCHEME_CACHE_SEC  = 30 * 60
    22  
    23  	FILE_INFO_CACHE_SIZE = 25000
    24  	FILE_INFO_CACHE_SEC  = 30 * 60
    25  
    26  	CLASS_GUEST_COUNT_CACHE_SIZE = model.CLASS_CACHE_SIZE
    27  	CLASS_GUEST_COUNT_CACHE_SEC  = 30 * 60
    28  
    29  	WEBHOOK_CACHE_SIZE = 25000
    30  	WEBHOOK_CACHE_SEC  = 15 * 60
    31  
    32  	EMOJI_CACHE_SIZE = 5000
    33  	EMOJI_CACHE_SEC  = 30 * 60
    34  
    35  	CLASS_PINNEDPOSTS_COUNTS_CACHE_SIZE = model.CLASS_CACHE_SIZE
    36  	CLASS_PINNEDPOSTS_COUNTS_CACHE_SEC  = 30 * 60
    37  
    38  	CLASS_MEMBERS_COUNTS_CACHE_SIZE = model.CLASS_CACHE_SIZE
    39  	CLASS_MEMBERS_COUNTS_CACHE_SEC  = 30 * 60
    40  
    41  	LAST_POSTS_CACHE_SIZE = 20000
    42  	LAST_POSTS_CACHE_SEC  = 30 * 60
    43  
    44  	TERMS_OF_SERVICE_CACHE_SIZE = 20000
    45  	TERMS_OF_SERVICE_CACHE_SEC  = 30 * 60
    46  	LAST_POST_TIME_CACHE_SIZE   = 25000
    47  	LAST_POST_TIME_CACHE_SEC    = 15 * 60
    48  
    49  	USER_PROFILE_BY_ID_CACHE_SIZE = 20000
    50  	USER_PROFILE_BY_ID_SEC        = 30 * 60
    51  
    52  	PROFILES_IN_CLASS_CACHE_SIZE = model.CLASS_CACHE_SIZE
    53  	PROFILES_IN_CLASS_CACHE_SEC  = 15 * 60
    54  
    55  	BRANCH_CACHE_SIZE = 20000
    56  	BRANCH_CACHE_SEC  = 30 * 60
    57  
    58  	CLEAR_CACHE_MESSAGE_DATA = ""
    59  
    60  	CLASS_CACHE_SEC = 15 * 60 // 15 mins
    61  )
    62  
    63  type LocalCacheStore struct {
    64  	store.Store
    65  	metrics einterfaces.MetricsInterface
    66  	cluster einterfaces.ClusterInterface
    67  
    68  	reaction      LocalCacheReactionStore
    69  	reactionCache cache.Cache
    70  
    71  	fileInfo      LocalCacheFileInfoStore
    72  	fileInfoCache cache.Cache
    73  
    74  	role                 LocalCacheRoleStore
    75  	roleCache            cache.Cache
    76  	rolePermissionsCache cache.Cache
    77  
    78  	scheme      LocalCacheSchemeStore
    79  	schemeCache cache.Cache
    80  
    81  	emoji              LocalCacheEmojiStore
    82  	emojiCacheById     cache.Cache
    83  	emojiIdCacheByName cache.Cache
    84  
    85  	class                  LocalCacheClassStore
    86  	classMemberCountsCache cache.Cache
    87  	classByIdCache         cache.Cache
    88  
    89  	webhook      LocalCacheWebhookStore
    90  	webhookCache cache.Cache
    91  
    92  	post               LocalCachePostStore
    93  	postLastPostsCache cache.Cache
    94  	lastPostTimeCache  cache.Cache
    95  
    96  	user                  LocalCacheUserStore
    97  	userProfileByIdsCache cache.Cache
    98  	profilesInClassCache  cache.Cache
    99  
   100  	branch                         LocalCacheBranchStore
   101  	branchAllBranchIdsForUserCache cache.Cache
   102  
   103  	termsOfService      LocalCacheTermsOfServiceStore
   104  	termsOfServiceCache cache.Cache
   105  }
   106  
   107  func NewLocalCacheLayer(baseStore store.Store, metrics einterfaces.MetricsInterface, cluster einterfaces.ClusterInterface, cacheProvider cache.Provider) LocalCacheStore {
   108  
   109  	localCacheStore := LocalCacheStore{
   110  		Store:   baseStore,
   111  		cluster: cluster,
   112  		metrics: metrics,
   113  	}
   114  	// Reactions
   115  	localCacheStore.reactionCache = cacheProvider.NewCacheWithParams(REACTION_CACHE_SIZE, "Reaction", REACTION_CACHE_SEC, model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_REACTIONS)
   116  	localCacheStore.reaction = LocalCacheReactionStore{ReactionStore: baseStore.Reaction(), rootStore: &localCacheStore}
   117  
   118  	// Roles
   119  	localCacheStore.roleCache = cacheProvider.NewCacheWithParams(ROLE_CACHE_SIZE, "Role", ROLE_CACHE_SEC, model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_ROLES)
   120  	localCacheStore.rolePermissionsCache = cacheProvider.NewCacheWithParams(ROLE_CACHE_SIZE, "RolePermission", ROLE_CACHE_SEC, model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_ROLE_PERMISSIONS)
   121  	localCacheStore.role = LocalCacheRoleStore{RoleStore: baseStore.Role(), rootStore: &localCacheStore}
   122  
   123  	// Schemes
   124  	localCacheStore.schemeCache = cacheProvider.NewCacheWithParams(SCHEME_CACHE_SIZE, "Scheme", SCHEME_CACHE_SEC, model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_SCHEMES)
   125  	localCacheStore.scheme = LocalCacheSchemeStore{SchemeStore: baseStore.Scheme(), rootStore: &localCacheStore}
   126  
   127  	// FileInfo
   128  	localCacheStore.fileInfoCache = cacheProvider.NewCacheWithParams(FILE_INFO_CACHE_SIZE, "FileInfo", FILE_INFO_CACHE_SEC, model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_FILE_INFOS)
   129  	localCacheStore.fileInfo = LocalCacheFileInfoStore{FileInfoStore: baseStore.FileInfo(), rootStore: &localCacheStore}
   130  
   131  	// Webhooks
   132  	localCacheStore.webhookCache = cacheProvider.NewCacheWithParams(WEBHOOK_CACHE_SIZE, "Webhook", WEBHOOK_CACHE_SEC, model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_WEBHOOKS)
   133  	localCacheStore.webhook = LocalCacheWebhookStore{WebhookStore: baseStore.Webhook(), rootStore: &localCacheStore}
   134  
   135  	// Emojis
   136  	localCacheStore.emojiCacheById = cacheProvider.NewCacheWithParams(EMOJI_CACHE_SIZE, "EmojiById", EMOJI_CACHE_SEC, model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_EMOJIS_BY_ID)
   137  	localCacheStore.emojiIdCacheByName = cacheProvider.NewCacheWithParams(EMOJI_CACHE_SIZE, "EmojiByName", EMOJI_CACHE_SEC, model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_EMOJIS_ID_BY_NAME)
   138  	localCacheStore.emoji = LocalCacheEmojiStore{EmojiStore: baseStore.Emoji(), rootStore: &localCacheStore}
   139  
   140  	// Classes
   141  	localCacheStore.classMemberCountsCache = cacheProvider.NewCacheWithParams(CLASS_MEMBERS_COUNTS_CACHE_SIZE, "ClassMemberCounts", CLASS_MEMBERS_COUNTS_CACHE_SEC, model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_CLASS_MEMBER_COUNTS)
   142  	localCacheStore.classByIdCache = cacheProvider.NewCacheWithParams(model.CLASS_CACHE_SIZE, "classById", CLASS_CACHE_SEC, model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_CLASS)
   143  	localCacheStore.class = LocalCacheClassStore{ClassStore: baseStore.Class(), rootStore: &localCacheStore}
   144  
   145  	// Posts
   146  	localCacheStore.postLastPostsCache = cacheProvider.NewCacheWithParams(LAST_POSTS_CACHE_SIZE, "LastPost", LAST_POSTS_CACHE_SEC, model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_LAST_POSTS)
   147  	localCacheStore.lastPostTimeCache = cacheProvider.NewCacheWithParams(LAST_POST_TIME_CACHE_SIZE, "LastPostTime", LAST_POST_TIME_CACHE_SEC, model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_LAST_POST_TIME)
   148  	localCacheStore.post = LocalCachePostStore{PostStore: baseStore.Post(), rootStore: &localCacheStore}
   149  
   150  	// TOS
   151  	localCacheStore.termsOfServiceCache = cacheProvider.NewCacheWithParams(TERMS_OF_SERVICE_CACHE_SIZE, "TermsOfService", TERMS_OF_SERVICE_CACHE_SEC, model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_TERMS_OF_SERVICE)
   152  	localCacheStore.termsOfService = LocalCacheTermsOfServiceStore{TermsOfServiceStore: baseStore.TermsOfService(), rootStore: &localCacheStore}
   153  
   154  	// Users
   155  	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)
   156  	localCacheStore.profilesInClassCache = cacheProvider.NewCacheWithParams(PROFILES_IN_CLASS_CACHE_SIZE, "ProfilesInClass", PROFILES_IN_CLASS_CACHE_SEC, model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_PROFILE_IN_CLASS)
   157  	localCacheStore.user = LocalCacheUserStore{UserStore: baseStore.User(), rootStore: &localCacheStore}
   158  
   159  	// Branches
   160  	localCacheStore.branchAllBranchIdsForUserCache = cacheProvider.NewCacheWithParams(BRANCH_CACHE_SIZE, "Branch", BRANCH_CACHE_SEC, model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_BRANCHES)
   161  	localCacheStore.branch = LocalCacheBranchStore{BranchStore: baseStore.Branch(), rootStore: &localCacheStore}
   162  
   163  	if cluster != nil {
   164  		cluster.RegisterClusterMessageHandler(model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_REACTIONS, localCacheStore.reaction.handleClusterInvalidateReaction)
   165  		cluster.RegisterClusterMessageHandler(model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_ROLES, localCacheStore.role.handleClusterInvalidateRole)
   166  		cluster.RegisterClusterMessageHandler(model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_ROLE_PERMISSIONS, localCacheStore.role.handleClusterInvalidateRolePermissions)
   167  		cluster.RegisterClusterMessageHandler(model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_SCHEMES, localCacheStore.scheme.handleClusterInvalidateScheme)
   168  		cluster.RegisterClusterMessageHandler(model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_FILE_INFOS, localCacheStore.fileInfo.handleClusterInvalidateFileInfo)
   169  		cluster.RegisterClusterMessageHandler(model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_LAST_POST_TIME, localCacheStore.post.handleClusterInvalidateLastPostTime)
   170  		cluster.RegisterClusterMessageHandler(model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_WEBHOOKS, localCacheStore.webhook.handleClusterInvalidateWebhook)
   171  		cluster.RegisterClusterMessageHandler(model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_EMOJIS_BY_ID, localCacheStore.emoji.handleClusterInvalidateEmojiById)
   172  		cluster.RegisterClusterMessageHandler(model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_EMOJIS_ID_BY_NAME, localCacheStore.emoji.handleClusterInvalidateEmojiIdByName)
   173  		cluster.RegisterClusterMessageHandler(model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_CLASS_MEMBER_COUNTS, localCacheStore.class.handleClusterInvalidateClassMemberCounts)
   174  		cluster.RegisterClusterMessageHandler(model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_CLASS, localCacheStore.class.handleClusterInvalidateClassById)
   175  		cluster.RegisterClusterMessageHandler(model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_LAST_POSTS, localCacheStore.post.handleClusterInvalidateLastPosts)
   176  		cluster.RegisterClusterMessageHandler(model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_TERMS_OF_SERVICE, localCacheStore.termsOfService.handleClusterInvalidateTermsOfService)
   177  		cluster.RegisterClusterMessageHandler(model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_PROFILE_BY_IDS, localCacheStore.user.handleClusterInvalidateScheme)
   178  		cluster.RegisterClusterMessageHandler(model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_PROFILE_IN_CLASS, localCacheStore.user.handleClusterInvalidateProfilesInClass)
   179  		cluster.RegisterClusterMessageHandler(model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_BRANCHES, localCacheStore.branch.handleClusterInvalidateBranch)
   180  	}
   181  	return localCacheStore
   182  }
   183  
   184  func (s LocalCacheStore) Reaction() store.ReactionStore {
   185  	return s.reaction
   186  }
   187  
   188  func (s LocalCacheStore) Role() store.RoleStore {
   189  	return s.role
   190  }
   191  
   192  func (s LocalCacheStore) Scheme() store.SchemeStore {
   193  	return s.scheme
   194  }
   195  
   196  func (s LocalCacheStore) FileInfo() store.FileInfoStore {
   197  	return s.fileInfo
   198  }
   199  
   200  func (s LocalCacheStore) Webhook() store.WebhookStore {
   201  	return s.webhook
   202  }
   203  
   204  func (s LocalCacheStore) Emoji() store.EmojiStore {
   205  	return s.emoji
   206  }
   207  
   208  func (s LocalCacheStore) Class() store.ClassStore {
   209  	return s.class
   210  }
   211  
   212  func (s LocalCacheStore) Post() store.PostStore {
   213  	return s.post
   214  }
   215  
   216  func (s LocalCacheStore) TermsOfService() store.TermsOfServiceStore {
   217  	return s.termsOfService
   218  }
   219  
   220  func (s LocalCacheStore) User() store.UserStore {
   221  	return s.user
   222  }
   223  
   224  func (s LocalCacheStore) Branch() store.BranchStore {
   225  	return s.branch
   226  }
   227  
   228  func (s LocalCacheStore) DropAllTables() {
   229  	s.Invalidate()
   230  	s.Store.DropAllTables()
   231  }
   232  
   233  func (s *LocalCacheStore) doInvalidateCacheCluster(cache cache.Cache, key string) {
   234  	cache.Remove(key)
   235  	if s.cluster != nil {
   236  		msg := &model.ClusterMessage{
   237  			Event:    cache.GetInvalidateClusterEvent(),
   238  			SendType: model.CLUSTER_SEND_BEST_EFFORT,
   239  			Data:     key,
   240  		}
   241  		s.cluster.SendClusterMessage(msg)
   242  	}
   243  }
   244  
   245  func (s *LocalCacheStore) doStandardAddToCache(cache cache.Cache, key string, value interface{}) {
   246  	cache.AddWithDefaultExpires(key, value)
   247  }
   248  
   249  func (s *LocalCacheStore) doStandardReadCache(cache cache.Cache, key string) interface{} {
   250  	if cacheItem, ok := cache.Get(key); ok {
   251  		if s.metrics != nil {
   252  			s.metrics.IncrementMemCacheHitCounter(cache.Name())
   253  		}
   254  		return cacheItem
   255  	}
   256  
   257  	if s.metrics != nil {
   258  		s.metrics.IncrementMemCacheMissCounter(cache.Name())
   259  	}
   260  
   261  	return nil
   262  }
   263  
   264  func (s *LocalCacheStore) doClearCacheCluster(cache cache.Cache) {
   265  	cache.Purge()
   266  	if s.cluster != nil {
   267  		msg := &model.ClusterMessage{
   268  			Event:    cache.GetInvalidateClusterEvent(),
   269  			SendType: model.CLUSTER_SEND_BEST_EFFORT,
   270  			Data:     CLEAR_CACHE_MESSAGE_DATA,
   271  		}
   272  		s.cluster.SendClusterMessage(msg)
   273  	}
   274  }
   275  
   276  func (s *LocalCacheStore) Invalidate() {
   277  	s.doClearCacheCluster(s.reactionCache)
   278  	s.doClearCacheCluster(s.schemeCache)
   279  	s.doClearCacheCluster(s.roleCache)
   280  	s.doClearCacheCluster(s.fileInfoCache)
   281  	s.doClearCacheCluster(s.webhookCache)
   282  	s.doClearCacheCluster(s.emojiCacheById)
   283  	s.doClearCacheCluster(s.emojiIdCacheByName)
   284  	s.doClearCacheCluster(s.classMemberCountsCache)
   285  	s.doClearCacheCluster(s.classByIdCache)
   286  	s.doClearCacheCluster(s.postLastPostsCache)
   287  	s.doClearCacheCluster(s.termsOfServiceCache)
   288  	s.doClearCacheCluster(s.lastPostTimeCache)
   289  	s.doClearCacheCluster(s.userProfileByIdsCache)
   290  	s.doClearCacheCluster(s.profilesInClassCache)
   291  	s.doClearCacheCluster(s.branchAllBranchIdsForUserCache)
   292  	s.doClearCacheCluster(s.rolePermissionsCache)
   293  }