github.com/masterhung0112/hk_server/v5@v5.0.0-20220302090640-ec71aef15e1c/store/localcachelayer/emoji_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  	"context"
     8  	"sync"
     9  
    10  	"github.com/masterhung0112/hk_server/v5/model"
    11  	"github.com/masterhung0112/hk_server/v5/store"
    12  	"github.com/masterhung0112/hk_server/v5/store/sqlstore"
    13  )
    14  
    15  type LocalCacheEmojiStore struct {
    16  	store.EmojiStore
    17  	rootStore                *LocalCacheStore
    18  	emojiByIdMut             sync.Mutex
    19  	emojiByIdInvalidations   map[string]bool
    20  	emojiByNameMut           sync.Mutex
    21  	emojiByNameInvalidations map[string]bool
    22  }
    23  
    24  func (es *LocalCacheEmojiStore) handleClusterInvalidateEmojiById(msg *model.ClusterMessage) {
    25  	if msg.Data == ClearCacheMessageData {
    26  		es.rootStore.emojiCacheById.Purge()
    27  	} else {
    28  		es.emojiByIdMut.Lock()
    29  		es.emojiByIdInvalidations[msg.Data] = true
    30  		es.emojiByIdMut.Unlock()
    31  		es.rootStore.emojiCacheById.Remove(msg.Data)
    32  	}
    33  }
    34  
    35  func (es *LocalCacheEmojiStore) handleClusterInvalidateEmojiIdByName(msg *model.ClusterMessage) {
    36  	if msg.Data == ClearCacheMessageData {
    37  		es.rootStore.emojiIdCacheByName.Purge()
    38  	} else {
    39  		es.emojiByNameMut.Lock()
    40  		es.emojiByNameInvalidations[msg.Data] = true
    41  		es.emojiByNameMut.Unlock()
    42  		es.rootStore.emojiIdCacheByName.Remove(msg.Data)
    43  	}
    44  }
    45  
    46  func (es *LocalCacheEmojiStore) Get(ctx context.Context, id string, allowFromCache bool) (*model.Emoji, error) {
    47  	if allowFromCache {
    48  		if emoji, ok := es.getFromCacheById(id); ok {
    49  			return emoji, nil
    50  		}
    51  	}
    52  
    53  	// If it was invalidated, then we need to query master.
    54  	es.emojiByIdMut.Lock()
    55  	if es.emojiByIdInvalidations[id] {
    56  		// And then remove the key from the map.
    57  		ctx = sqlstore.WithMaster(ctx)
    58  		delete(es.emojiByIdInvalidations, id)
    59  	}
    60  	es.emojiByIdMut.Unlock()
    61  
    62  	emoji, err := es.EmojiStore.Get(ctx, id, allowFromCache)
    63  
    64  	if allowFromCache && err == nil {
    65  		es.addToCache(emoji)
    66  	}
    67  
    68  	return emoji, err
    69  }
    70  
    71  func (es *LocalCacheEmojiStore) GetByName(ctx context.Context, name string, allowFromCache bool) (*model.Emoji, error) {
    72  	if id, ok := model.GetSystemEmojiId(name); ok {
    73  		return es.Get(ctx, id, allowFromCache)
    74  	}
    75  
    76  	if allowFromCache {
    77  		if emoji, ok := es.getFromCacheByName(name); ok {
    78  			return emoji, nil
    79  		}
    80  	}
    81  
    82  	// If it was invalidated, then we need to query master.
    83  	es.emojiByNameMut.Lock()
    84  	if es.emojiByNameInvalidations[name] {
    85  		ctx = sqlstore.WithMaster(ctx)
    86  		// And then remove the key from the map.
    87  		delete(es.emojiByNameInvalidations, name)
    88  	}
    89  	es.emojiByNameMut.Unlock()
    90  
    91  	emoji, err := es.EmojiStore.GetByName(ctx, name, allowFromCache)
    92  
    93  	if allowFromCache && err == nil {
    94  		es.addToCache(emoji)
    95  	}
    96  
    97  	return emoji, err
    98  }
    99  
   100  func (es *LocalCacheEmojiStore) Delete(emoji *model.Emoji, time int64) error {
   101  	err := es.EmojiStore.Delete(emoji, time)
   102  
   103  	if err == nil {
   104  		es.removeFromCache(emoji)
   105  	}
   106  
   107  	return err
   108  }
   109  
   110  func (es *LocalCacheEmojiStore) addToCache(emoji *model.Emoji) {
   111  	es.rootStore.doStandardAddToCache(es.rootStore.emojiCacheById, emoji.Id, emoji)
   112  	es.rootStore.doStandardAddToCache(es.rootStore.emojiIdCacheByName, emoji.Name, emoji.Id)
   113  }
   114  
   115  func (es *LocalCacheEmojiStore) getFromCacheById(id string) (*model.Emoji, bool) {
   116  	var emoji *model.Emoji
   117  	if err := es.rootStore.doStandardReadCache(es.rootStore.emojiCacheById, id, &emoji); err == nil {
   118  		return emoji, true
   119  	}
   120  	return nil, false
   121  }
   122  
   123  func (es *LocalCacheEmojiStore) getFromCacheByName(name string) (*model.Emoji, bool) {
   124  	var emojiId string
   125  	if err := es.rootStore.doStandardReadCache(es.rootStore.emojiIdCacheByName, name, &emojiId); err == nil {
   126  		return es.getFromCacheById(emojiId)
   127  	}
   128  	return nil, false
   129  }
   130  
   131  func (es *LocalCacheEmojiStore) removeFromCache(emoji *model.Emoji) {
   132  	es.emojiByIdMut.Lock()
   133  	es.emojiByIdInvalidations[emoji.Id] = true
   134  	es.emojiByIdMut.Unlock()
   135  	es.rootStore.doInvalidateCacheCluster(es.rootStore.emojiCacheById, emoji.Id)
   136  
   137  	es.emojiByNameMut.Lock()
   138  	es.emojiByNameInvalidations[emoji.Name] = true
   139  	es.emojiByNameMut.Unlock()
   140  	es.rootStore.doInvalidateCacheCluster(es.rootStore.emojiIdCacheByName, emoji.Name)
   141  }