github.com/xzl8028/xenia-server@v0.0.0-20190809101854-18450a97da63/store/local_cache_supplier.go (about)

     1  // Copyright (c) 2016-present Xenia, Inc. All Rights Reserved.
     2  // See License.txt for license information.
     3  
     4  package store
     5  
     6  import (
     7  	"context"
     8  
     9  	"github.com/xzl8028/xenia-server/einterfaces"
    10  	"github.com/xzl8028/xenia-server/model"
    11  	"github.com/xzl8028/xenia-server/utils"
    12  )
    13  
    14  const (
    15  	REACTION_CACHE_SIZE = 20000
    16  	REACTION_CACHE_SEC  = 30 * 60
    17  
    18  	ROLE_CACHE_SIZE = 20000
    19  	ROLE_CACHE_SEC  = 30 * 60
    20  
    21  	SCHEME_CACHE_SIZE = 20000
    22  	SCHEME_CACHE_SEC  = 30 * 60
    23  
    24  	GROUP_CACHE_SIZE = 20000
    25  	GROUP_CACHE_SEC  = 30 * 60
    26  
    27  	CLEAR_CACHE_MESSAGE_DATA = ""
    28  )
    29  
    30  type LocalCacheSupplier struct {
    31  	next          LayeredStoreSupplier
    32  	reactionCache *utils.Cache
    33  	roleCache     *utils.Cache
    34  	schemeCache   *utils.Cache
    35  	metrics       einterfaces.MetricsInterface
    36  	cluster       einterfaces.ClusterInterface
    37  }
    38  
    39  // Caching Interface
    40  type ObjectCache interface {
    41  	AddWithExpiresInSecs(key, value interface{}, expireAtSecs int64)
    42  	AddWithDefaultExpires(key, value interface{})
    43  	Purge()
    44  	Get(key interface{}) (value interface{}, ok bool)
    45  	Remove(key interface{})
    46  	Len() int
    47  	Name() string
    48  	GetInvalidateClusterEvent() string
    49  }
    50  
    51  func NewLocalCacheSupplier(metrics einterfaces.MetricsInterface, cluster einterfaces.ClusterInterface) *LocalCacheSupplier {
    52  	supplier := &LocalCacheSupplier{
    53  		reactionCache: utils.NewLruWithParams(REACTION_CACHE_SIZE, "Reaction", REACTION_CACHE_SEC, model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_REACTIONS),
    54  		roleCache:     utils.NewLruWithParams(ROLE_CACHE_SIZE, "Role", ROLE_CACHE_SEC, model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_ROLES),
    55  		schemeCache:   utils.NewLruWithParams(SCHEME_CACHE_SIZE, "Scheme", SCHEME_CACHE_SEC, model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_SCHEMES),
    56  		metrics:       metrics,
    57  		cluster:       cluster,
    58  	}
    59  
    60  	if cluster != nil {
    61  		cluster.RegisterClusterMessageHandler(model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_REACTIONS, supplier.handleClusterInvalidateReaction)
    62  		cluster.RegisterClusterMessageHandler(model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_ROLES, supplier.handleClusterInvalidateRole)
    63  	}
    64  
    65  	return supplier
    66  }
    67  
    68  func (s *LocalCacheSupplier) SetChainNext(next LayeredStoreSupplier) {
    69  	s.next = next
    70  }
    71  
    72  func (s *LocalCacheSupplier) Next() LayeredStoreSupplier {
    73  	return s.next
    74  }
    75  
    76  func (s *LocalCacheSupplier) doStandardReadCache(ctx context.Context, cache ObjectCache, key string, hints ...LayeredStoreHint) *LayeredStoreSupplierResult {
    77  	if hintsContains(hints, LSH_NO_CACHE) {
    78  		if s.metrics != nil {
    79  			s.metrics.IncrementMemCacheMissCounter(cache.Name())
    80  		}
    81  		return nil
    82  	}
    83  
    84  	if cacheItem, ok := cache.Get(key); ok {
    85  		if s.metrics != nil {
    86  			s.metrics.IncrementMemCacheHitCounter(cache.Name())
    87  		}
    88  		result := NewSupplierResult()
    89  		result.Data = cacheItem
    90  		return result
    91  	}
    92  
    93  	if s.metrics != nil {
    94  		s.metrics.IncrementMemCacheMissCounter(cache.Name())
    95  	}
    96  
    97  	return nil
    98  }
    99  
   100  func (s *LocalCacheSupplier) doStandardAddToCache(ctx context.Context, cache ObjectCache, key string, result *LayeredStoreSupplierResult, hints ...LayeredStoreHint) {
   101  	if result.Err == nil && result.Data != nil {
   102  		cache.AddWithDefaultExpires(key, result.Data)
   103  	}
   104  }
   105  
   106  func (s *LocalCacheSupplier) doInvalidateCacheCluster(cache ObjectCache, key string) {
   107  	cache.Remove(key)
   108  	if s.cluster != nil {
   109  		msg := &model.ClusterMessage{
   110  			Event:    cache.GetInvalidateClusterEvent(),
   111  			SendType: model.CLUSTER_SEND_BEST_EFFORT,
   112  			Data:     key,
   113  		}
   114  		s.cluster.SendClusterMessage(msg)
   115  	}
   116  }
   117  
   118  func (s *LocalCacheSupplier) doClearCacheCluster(cache ObjectCache) {
   119  	cache.Purge()
   120  	if s.cluster != nil {
   121  		msg := &model.ClusterMessage{
   122  			Event:    cache.GetInvalidateClusterEvent(),
   123  			SendType: model.CLUSTER_SEND_BEST_EFFORT,
   124  			Data:     CLEAR_CACHE_MESSAGE_DATA,
   125  		}
   126  		s.cluster.SendClusterMessage(msg)
   127  	}
   128  }
   129  
   130  func (s *LocalCacheSupplier) Invalidate() {
   131  	s.doClearCacheCluster(s.reactionCache)
   132  	s.doClearCacheCluster(s.roleCache)
   133  	s.doClearCacheCluster(s.schemeCache)
   134  }