mirror of
https://github.com/aykhans/slash-e.git
synced 2025-04-18 13:15:27 +00:00
feat: update store cache
This commit is contained in:
parent
be7efdd8d4
commit
a1f66e3df2
20
api/cache.go
20
api/cache.go
@ -1,20 +0,0 @@
|
||||
package api
|
||||
|
||||
// CacheNamespace is the type of a cache.
|
||||
type CacheNamespace string
|
||||
|
||||
const (
|
||||
// UserCache is the cache type of workspaces.
|
||||
WorkspaceCache CacheNamespace = "w"
|
||||
// UserCache is the cache type of users.
|
||||
UserCache CacheNamespace = "u"
|
||||
// ShortcutCache is the cache type of shortcuts.
|
||||
ShortcutCache CacheNamespace = "s"
|
||||
)
|
||||
|
||||
// CacheService is the service for caches.
|
||||
type CacheService interface {
|
||||
FindCache(namespace CacheNamespace, id int, entry interface{}) (bool, error)
|
||||
UpsertCache(namespace CacheNamespace, id int, entry interface{}) error
|
||||
DeleteCache(namespace CacheNamespace, id int)
|
||||
}
|
@ -1,72 +1 @@
|
||||
package store
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"encoding/gob"
|
||||
"fmt"
|
||||
|
||||
"github.com/VictoriaMetrics/fastcache"
|
||||
"github.com/boojack/corgi/api"
|
||||
)
|
||||
|
||||
var (
|
||||
// 64 MiB.
|
||||
cacheSize = 1024 * 1024 * 64
|
||||
_ api.CacheService = (*CacheService)(nil)
|
||||
)
|
||||
|
||||
// CacheService implements a cache.
|
||||
type CacheService struct {
|
||||
cache *fastcache.Cache
|
||||
}
|
||||
|
||||
// NewCacheService creates a cache service.
|
||||
func NewCacheService() *CacheService {
|
||||
return &CacheService{
|
||||
cache: fastcache.New(cacheSize),
|
||||
}
|
||||
}
|
||||
|
||||
// FindCache finds the value in cache.
|
||||
func (s *CacheService) FindCache(namespace api.CacheNamespace, id int, entry interface{}) (bool, error) {
|
||||
buf1 := []byte{0, 0, 0, 0, 0, 0, 0, 0}
|
||||
binary.LittleEndian.PutUint64(buf1, uint64(id))
|
||||
|
||||
buf2, has := s.cache.HasGet(nil, append([]byte(namespace), buf1...))
|
||||
if has {
|
||||
dec := gob.NewDecoder(bytes.NewReader(buf2))
|
||||
if err := dec.Decode(entry); err != nil {
|
||||
return false, fmt.Errorf("failed to decode entry for cache namespace: %s, error: %w", namespace, err)
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
|
||||
return false, nil
|
||||
}
|
||||
|
||||
// UpsertCache upserts the value to cache.
|
||||
func (s *CacheService) UpsertCache(namespace api.CacheNamespace, id int, entry interface{}) error {
|
||||
buf1 := []byte{0, 0, 0, 0, 0, 0, 0, 0}
|
||||
binary.LittleEndian.PutUint64(buf1, uint64(id))
|
||||
|
||||
var buf2 bytes.Buffer
|
||||
enc := gob.NewEncoder(&buf2)
|
||||
if err := enc.Encode(entry); err != nil {
|
||||
return fmt.Errorf("failed to encode entry for cache namespace: %s, error: %w", namespace, err)
|
||||
}
|
||||
s.cache.Set(append([]byte(namespace), buf1...), buf2.Bytes())
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeleteCache deletes the cache.
|
||||
func (s *CacheService) DeleteCache(namespace api.CacheNamespace, id int) {
|
||||
buf1 := []byte{0, 0, 0, 0, 0, 0, 0, 0}
|
||||
binary.LittleEndian.PutUint64(buf1, uint64(id))
|
||||
|
||||
_, has := s.cache.HasGet(nil, append([]byte(namespace), buf1...))
|
||||
if has {
|
||||
s.cache.Del(append([]byte(namespace), buf1...))
|
||||
}
|
||||
}
|
||||
|
@ -76,12 +76,8 @@ func (s *Store) CreateShortcut(ctx context.Context, create *api.ShortcutCreate)
|
||||
return nil, FormatError(err)
|
||||
}
|
||||
|
||||
s.shortcutCache.Store(shortcutRaw.ID, shortcutRaw)
|
||||
shortcut := shortcutRaw.toShortcut()
|
||||
|
||||
if err := s.cache.UpsertCache(api.ShortcutCache, shortcut.ID, shortcut); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return shortcut, nil
|
||||
}
|
||||
|
||||
@ -101,12 +97,8 @@ func (s *Store) PatchShortcut(ctx context.Context, patch *api.ShortcutPatch) (*a
|
||||
return nil, FormatError(err)
|
||||
}
|
||||
|
||||
s.shortcutCache.Store(shortcutRaw.ID, shortcutRaw)
|
||||
shortcut := shortcutRaw.toShortcut()
|
||||
|
||||
if err := s.cache.UpsertCache(api.ShortcutCache, shortcut.ID, shortcut); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return shortcut, nil
|
||||
}
|
||||
|
||||
@ -123,8 +115,9 @@ func (s *Store) FindShortcutList(ctx context.Context, find *api.ShortcutFind) ([
|
||||
}
|
||||
|
||||
list := []*api.Shortcut{}
|
||||
for _, raw := range shortcutRawList {
|
||||
list = append(list, raw.toShortcut())
|
||||
for _, shortcutRaw := range shortcutRawList {
|
||||
s.shortcutCache.Store(shortcutRaw.ID, shortcutRaw)
|
||||
list = append(list, shortcutRaw.toShortcut())
|
||||
}
|
||||
|
||||
return list, nil
|
||||
@ -132,13 +125,8 @@ func (s *Store) FindShortcutList(ctx context.Context, find *api.ShortcutFind) ([
|
||||
|
||||
func (s *Store) FindShortcut(ctx context.Context, find *api.ShortcutFind) (*api.Shortcut, error) {
|
||||
if find.ID != nil {
|
||||
shortcut := &api.Shortcut{}
|
||||
has, err := s.cache.FindCache(api.ShortcutCache, *find.ID, shortcut)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if has {
|
||||
return shortcut, nil
|
||||
if cache, ok := s.shortcutCache.Load(*find.ID); ok {
|
||||
return cache.(*shortcutRaw).toShortcut(), nil
|
||||
}
|
||||
}
|
||||
|
||||
@ -157,12 +145,9 @@ func (s *Store) FindShortcut(ctx context.Context, find *api.ShortcutFind) (*api.
|
||||
return nil, &common.Error{Code: common.NotFound, Err: fmt.Errorf("not found")}
|
||||
}
|
||||
|
||||
shortcut := list[0].toShortcut()
|
||||
|
||||
if err := s.cache.UpsertCache(api.ShortcutCache, shortcut.ID, shortcut); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
shortcutRaw := list[0]
|
||||
s.shortcutCache.Store(shortcutRaw.ID, shortcutRaw)
|
||||
shortcut := shortcutRaw.toShortcut()
|
||||
return shortcut, nil
|
||||
}
|
||||
|
||||
@ -183,7 +168,7 @@ func (s *Store) DeleteShortcut(ctx context.Context, delete *api.ShortcutDelete)
|
||||
}
|
||||
|
||||
if delete.ID != nil {
|
||||
s.cache.DeleteCache(api.ShortcutCache, *delete.ID)
|
||||
s.shortcutCache.Delete(*delete.ID)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
@ -2,8 +2,8 @@ package store
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"sync"
|
||||
|
||||
"github.com/boojack/corgi/api"
|
||||
"github.com/boojack/corgi/server/profile"
|
||||
)
|
||||
|
||||
@ -11,16 +11,16 @@ import (
|
||||
type Store struct {
|
||||
db *sql.DB
|
||||
profile *profile.Profile
|
||||
cache api.CacheService
|
||||
|
||||
userCache sync.Map // map[int]*userRaw
|
||||
workspaceCache sync.Map // map[int]*memoRaw
|
||||
shortcutCache sync.Map // map[int]*shortcutRaw
|
||||
}
|
||||
|
||||
// New creates a new instance of Store.
|
||||
func New(db *sql.DB, profile *profile.Profile) *Store {
|
||||
cacheService := NewCacheService()
|
||||
|
||||
return &Store{
|
||||
db: db,
|
||||
profile: profile,
|
||||
cache: cacheService,
|
||||
}
|
||||
}
|
||||
|
@ -58,12 +58,8 @@ func (s *Store) CreateUser(ctx context.Context, create *api.UserCreate) (*api.Us
|
||||
return nil, FormatError(err)
|
||||
}
|
||||
|
||||
s.userCache.Store(userRaw.ID, userRaw)
|
||||
user := userRaw.toUser()
|
||||
|
||||
if err := s.cache.UpsertCache(api.UserCache, user.ID, user); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return user, nil
|
||||
}
|
||||
|
||||
@ -83,12 +79,8 @@ func (s *Store) PatchUser(ctx context.Context, patch *api.UserPatch) (*api.User,
|
||||
return nil, FormatError(err)
|
||||
}
|
||||
|
||||
s.userCache.Store(userRaw.ID, userRaw)
|
||||
user := userRaw.toUser()
|
||||
|
||||
if err := s.cache.UpsertCache(api.UserCache, user.ID, user); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return user, nil
|
||||
}
|
||||
|
||||
@ -105,14 +97,21 @@ func (s *Store) FindUserList(ctx context.Context, find *api.UserFind) ([]*api.Us
|
||||
}
|
||||
|
||||
list := []*api.User{}
|
||||
for _, raw := range userRawList {
|
||||
list = append(list, raw.toUser())
|
||||
for _, userRaw := range userRawList {
|
||||
s.userCache.Store(userRaw.ID, userRaw)
|
||||
list = append(list, userRaw.toUser())
|
||||
}
|
||||
|
||||
return list, nil
|
||||
}
|
||||
|
||||
func (s *Store) FindUser(ctx context.Context, find *api.UserFind) (*api.User, error) {
|
||||
if find.ID != nil {
|
||||
if cache, ok := s.userCache.Load(*find.ID); ok {
|
||||
return cache.(*userRaw).toUser(), nil
|
||||
}
|
||||
}
|
||||
|
||||
tx, err := s.db.BeginTx(ctx, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -130,11 +129,9 @@ func (s *Store) FindUser(ctx context.Context, find *api.UserFind) (*api.User, er
|
||||
return nil, &common.Error{Code: common.Conflict, Err: fmt.Errorf("found %d users with filter %+v, expect 1", len(list), find)}
|
||||
}
|
||||
|
||||
user := list[0].toUser()
|
||||
if err := s.cache.UpsertCache(api.UserCache, user.ID, user); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
userRaw := list[0]
|
||||
s.userCache.Store(userRaw.ID, userRaw)
|
||||
user := userRaw.toUser()
|
||||
return user, nil
|
||||
}
|
||||
|
||||
@ -154,8 +151,7 @@ func (s *Store) DeleteUser(ctx context.Context, delete *api.UserDelete) error {
|
||||
return FormatError(err)
|
||||
}
|
||||
|
||||
s.cache.DeleteCache(api.UserCache, delete.ID)
|
||||
|
||||
s.userCache.Delete(delete.ID)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -58,12 +58,8 @@ func (s *Store) CreateWorkspace(ctx context.Context, create *api.WorkspaceCreate
|
||||
return nil, FormatError(err)
|
||||
}
|
||||
|
||||
s.workspaceCache.Store(workspaceRaw.ID, workspaceRaw)
|
||||
workspace := workspaceRaw.toWorkspace()
|
||||
|
||||
if err := s.cache.UpsertCache(api.WorkspaceCache, workspace.ID, workspace); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return workspace, nil
|
||||
}
|
||||
|
||||
@ -83,12 +79,8 @@ func (s *Store) PatchWorkspace(ctx context.Context, patch *api.WorkspacePatch) (
|
||||
return nil, FormatError(err)
|
||||
}
|
||||
|
||||
s.workspaceCache.Store(workspaceRaw.ID, workspaceRaw)
|
||||
workspace := workspaceRaw.toWorkspace()
|
||||
|
||||
if err := s.cache.UpsertCache(api.WorkspaceCache, workspace.ID, workspace); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return workspace, nil
|
||||
}
|
||||
|
||||
@ -105,8 +97,9 @@ func (s *Store) FindWordspaceList(ctx context.Context, find *api.WorkspaceFind)
|
||||
}
|
||||
|
||||
list := []*api.Workspace{}
|
||||
for _, raw := range workspaceRawList {
|
||||
list = append(list, raw.toWorkspace())
|
||||
for _, workspaceRaw := range workspaceRawList {
|
||||
s.workspaceCache.Store(workspaceRaw.ID, workspaceRaw)
|
||||
list = append(list, workspaceRaw.toWorkspace())
|
||||
}
|
||||
|
||||
return list, nil
|
||||
@ -114,13 +107,8 @@ func (s *Store) FindWordspaceList(ctx context.Context, find *api.WorkspaceFind)
|
||||
|
||||
func (s *Store) FindWorkspace(ctx context.Context, find *api.WorkspaceFind) (*api.Workspace, error) {
|
||||
if find.ID != nil {
|
||||
workspace := &api.Workspace{}
|
||||
has, err := s.cache.FindCache(api.WorkspaceCache, *find.ID, workspace)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if has {
|
||||
return workspace, nil
|
||||
if cache, ok := s.workspaceCache.Load(*find.ID); ok {
|
||||
return cache.(*workspaceRaw).toWorkspace(), nil
|
||||
}
|
||||
}
|
||||
|
||||
@ -141,12 +129,9 @@ func (s *Store) FindWorkspace(ctx context.Context, find *api.WorkspaceFind) (*ap
|
||||
return nil, &common.Error{Code: common.Conflict, Err: fmt.Errorf("found %d workspaces with filter %+v, expect 1", len(list), find)}
|
||||
}
|
||||
|
||||
workspace := list[0].toWorkspace()
|
||||
|
||||
if err := s.cache.UpsertCache(api.WorkspaceCache, workspace.ID, workspace); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
workspaceRaw := list[0]
|
||||
s.workspaceCache.Store(workspaceRaw.ID, workspaceRaw)
|
||||
workspace := workspaceRaw.toWorkspace()
|
||||
return workspace, nil
|
||||
}
|
||||
|
||||
@ -166,8 +151,7 @@ func (s *Store) DeleteWorkspace(ctx context.Context, delete *api.WorkspaceDelete
|
||||
return FormatError(err)
|
||||
}
|
||||
|
||||
s.cache.DeleteCache(api.WorkspaceCache, delete.ID)
|
||||
|
||||
s.workspaceCache.Delete(delete.ID)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user