github.com/mattermosttest/mattermost-server/v5@v5.0.0-20200917143240-9dfa12e121f9/store/localcachelayer/post_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  	"strconv"
     8  	"strings"
     9  
    10  	"github.com/mattermost/mattermost-server/v5/model"
    11  	"github.com/mattermost/mattermost-server/v5/store"
    12  
    13  	"fmt"
    14  )
    15  
    16  type LocalCachePostStore struct {
    17  	store.PostStore
    18  	rootStore *LocalCacheStore
    19  }
    20  
    21  func (s *LocalCachePostStore) handleClusterInvalidateLastPostTime(msg *model.ClusterMessage) {
    22  	if msg.Data == CLEAR_CACHE_MESSAGE_DATA {
    23  		s.rootStore.lastPostTimeCache.Purge()
    24  	} else {
    25  		s.rootStore.lastPostTimeCache.Remove(msg.Data)
    26  	}
    27  }
    28  
    29  func (s *LocalCachePostStore) handleClusterInvalidateLastPosts(msg *model.ClusterMessage) {
    30  	if msg.Data == CLEAR_CACHE_MESSAGE_DATA {
    31  		s.rootStore.postLastPostsCache.Purge()
    32  	} else {
    33  		s.rootStore.postLastPostsCache.Remove(msg.Data)
    34  	}
    35  }
    36  
    37  func (s LocalCachePostStore) ClearCaches() {
    38  	s.rootStore.doClearCacheCluster(s.rootStore.lastPostTimeCache)
    39  	s.rootStore.doClearCacheCluster(s.rootStore.postLastPostsCache)
    40  	s.PostStore.ClearCaches()
    41  
    42  	if s.rootStore.metrics != nil {
    43  		s.rootStore.metrics.IncrementMemCacheInvalidationCounter("Last Post Time - Purge")
    44  		s.rootStore.metrics.IncrementMemCacheInvalidationCounter("Last Posts Cache - Purge")
    45  	}
    46  }
    47  
    48  func (s LocalCachePostStore) InvalidateLastPostTimeCache(channelId string) {
    49  	s.rootStore.doInvalidateCacheCluster(s.rootStore.lastPostTimeCache, channelId)
    50  
    51  	// Keys are "{channelid}{limit}" and caching only occurs on limits of 30 and 60
    52  	s.rootStore.doInvalidateCacheCluster(s.rootStore.postLastPostsCache, channelId+"30")
    53  	s.rootStore.doInvalidateCacheCluster(s.rootStore.postLastPostsCache, channelId+"60")
    54  
    55  	s.PostStore.InvalidateLastPostTimeCache(channelId)
    56  
    57  	if s.rootStore.metrics != nil {
    58  		s.rootStore.metrics.IncrementMemCacheInvalidationCounter("Last Post Time - Remove by Channel Id")
    59  		s.rootStore.metrics.IncrementMemCacheInvalidationCounter("Last Posts Cache - Remove by Channel Id")
    60  	}
    61  }
    62  
    63  func (s LocalCachePostStore) GetEtag(channelId string, allowFromCache bool) string {
    64  	if allowFromCache {
    65  		var lastTime int64
    66  		if err := s.rootStore.doStandardReadCache(s.rootStore.lastPostTimeCache, channelId, &lastTime); err == nil {
    67  			return fmt.Sprintf("%v.%v", model.CurrentVersion, lastTime)
    68  		}
    69  	}
    70  
    71  	result := s.PostStore.GetEtag(channelId, allowFromCache)
    72  
    73  	splittedResult := strings.Split(result, ".")
    74  
    75  	lastTime, _ := strconv.ParseInt((splittedResult[len(splittedResult)-1]), 10, 64)
    76  
    77  	s.rootStore.doStandardAddToCache(s.rootStore.lastPostTimeCache, channelId, lastTime)
    78  
    79  	return result
    80  }
    81  
    82  func (s LocalCachePostStore) GetPostsSince(options model.GetPostsSinceOptions, allowFromCache bool) (*model.PostList, *model.AppError) {
    83  	if allowFromCache {
    84  		// If the last post in the channel's time is less than or equal to the time we are getting posts since,
    85  		// we can safely return no posts.
    86  		var lastTime int64
    87  		if err := s.rootStore.doStandardReadCache(s.rootStore.lastPostTimeCache, options.ChannelId, &lastTime); err == nil && lastTime <= options.Time {
    88  			list := model.NewPostList()
    89  			return list, nil
    90  		}
    91  	}
    92  
    93  	list, err := s.PostStore.GetPostsSince(options, allowFromCache)
    94  
    95  	latestUpdate := options.Time
    96  	if err == nil {
    97  		for _, p := range list.ToSlice() {
    98  			if latestUpdate < p.UpdateAt {
    99  				latestUpdate = p.UpdateAt
   100  			}
   101  		}
   102  		s.rootStore.doStandardAddToCache(s.rootStore.lastPostTimeCache, options.ChannelId, latestUpdate)
   103  	}
   104  
   105  	return list, err
   106  }
   107  
   108  func (s LocalCachePostStore) GetPosts(options model.GetPostsOptions, allowFromCache bool) (*model.PostList, *model.AppError) {
   109  	if !allowFromCache {
   110  		return s.PostStore.GetPosts(options, allowFromCache)
   111  	}
   112  
   113  	offset := options.PerPage * options.Page
   114  	// Caching only occurs on limits of 30 and 60, the common limits requested by MM clients
   115  	if offset == 0 && (options.PerPage == 60 || options.PerPage == 30) {
   116  		var cacheItem *model.PostList
   117  		if err := s.rootStore.doStandardReadCache(s.rootStore.postLastPostsCache, fmt.Sprintf("%s%v", options.ChannelId, options.PerPage), &cacheItem); err == nil {
   118  			return cacheItem, nil
   119  		}
   120  	}
   121  
   122  	list, err := s.PostStore.GetPosts(options, false)
   123  	if err != nil {
   124  		return nil, err
   125  	}
   126  
   127  	// Caching only occurs on limits of 30 and 60, the common limits requested by MM clients
   128  	if offset == 0 && (options.PerPage == 60 || options.PerPage == 30) {
   129  		s.rootStore.doStandardAddToCache(s.rootStore.postLastPostsCache, fmt.Sprintf("%s%v", options.ChannelId, options.PerPage), list)
   130  	}
   131  
   132  	return list, err
   133  }