From 3590d3f8b60175572c498edf3b81c0d5c285b8e0 Mon Sep 17 00:00:00 2001 From: boojack Date: Sat, 11 Feb 2023 14:19:26 +0800 Subject: [PATCH] feat: update store cache (#1066) * feat: update store cache * chore: update --- go.mod | 3 -- go.sum | 9 ----- server/rss.go | 84 +++++++++++++++++++++---------------------- store/cache.go | 77 +++------------------------------------ store/memo.go | 77 ++++++++++++++++----------------------- store/shortcut.go | 28 ++++----------- store/store.go | 10 +++--- store/user.go | 33 ++++------------- store/user_setting.go | 16 +++++++-- 9 files changed, 109 insertions(+), 228 deletions(-) diff --git a/go.mod b/go.mod index 4646a6ea..58b03121 100644 --- a/go.mod +++ b/go.mod @@ -14,7 +14,6 @@ require ( require github.com/labstack/echo/v4 v4.9.0 require ( - github.com/VictoriaMetrics/fastcache v1.10.0 github.com/gorilla/feeds v1.1.1 github.com/gorilla/sessions v1.2.1 github.com/labstack/echo-contrib v0.13.0 @@ -22,10 +21,8 @@ require ( require ( github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 // indirect - github.com/cespare/xxhash/v2 v2.1.2 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/golang-jwt/jwt v3.2.2+incompatible // indirect - github.com/golang/snappy v0.0.4 // indirect github.com/gorilla/context v1.1.1 // indirect github.com/gorilla/securecookie v1.1.1 // indirect github.com/kr/pretty v0.3.1 // indirect diff --git a/go.sum b/go.sum index e7aa0f39..1764369a 100644 --- a/go.sum +++ b/go.sum @@ -1,20 +1,12 @@ -github.com/VictoriaMetrics/fastcache v1.10.0 h1:5hDJnLsKLpnUEToub7ETuRu8RCkb40woBZAUiKonXzY= -github.com/VictoriaMetrics/fastcache v1.10.0/go.mod h1:tjiYeEfYXCqacuvYw/7UoDIeJaNxq6132xHICNP77w8= -github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156 h1:eMwmnE/GDgah4HI848JfFxHt+iPb26b4zyfspmqY0/8= -github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8= github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 h1:DDGfHa7BWjL4YnC6+E63dPcxHo2sUxDIu8g3QgEJdRY= github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4= -github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE= -github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY= github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= -github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= -github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gorilla/context v1.1.1 h1:AWwleXJkX/nhcU9bZSnZoi3h/qGYqQAGhq6zZe/aQW8= @@ -88,7 +80,6 @@ golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211103235746-7861aae1554b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220405052023-b1e9470b6e64/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0 h1:kunALQeHf1/185U1i0GOB/fy1IPRDDpuoOOqRReG57U= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/text v0.4.0 h1:BrVqGRd7+k1DiOgtnFvAkoQEWQvBc25ouMJM6429SFg= diff --git a/server/rss.go b/server/rss.go index f034634c..ca82bb7e 100644 --- a/server/rss.go +++ b/server/rss.go @@ -13,48 +13,6 @@ import ( "github.com/usememos/memos/api" ) -func generateRSSFromMemoList(memoList []*api.Memo, baseURL string, profile *api.CustomizedProfile) (string, error) { - feed := &feeds.Feed{ - Title: profile.Name, - Link: &feeds.Link{Href: baseURL}, - Description: profile.Description, - Created: time.Now(), - } - - feed.Items = make([]*feeds.Item, len(memoList)) - for i, memo := range memoList { - var useTitle = strings.HasPrefix(memo.Content, "# ") - - var title string - if useTitle { - title = strings.Split(memo.Content, "\n")[0][2:] - } else { - title = memo.Creator.Username + "-memos-" + strconv.Itoa(memo.ID) - } - - var description string - if useTitle { - var firstLineEnd = strings.Index(memo.Content, "\n") - description = memo.Content[firstLineEnd+1:] - } else { - description = memo.Content - } - - feed.Items[i] = &feeds.Item{ - Title: title, - Link: &feeds.Link{Href: baseURL + "/m/" + strconv.Itoa(memo.ID)}, - Description: description, - Created: time.Unix(memo.CreatedTs, 0), - } - } - - rss, err := feed.ToRss() - if err != nil { - return "", err - } - return rss, nil -} - func (s *Server) registerRSSRoutes(g *echo.Group) { g.GET("/explore/rss.xml", func(c echo.Context) error { ctx := c.Request().Context() @@ -123,6 +81,48 @@ func (s *Server) registerRSSRoutes(g *echo.Group) { }) } +func generateRSSFromMemoList(memoList []*api.Memo, baseURL string, profile *api.CustomizedProfile) (string, error) { + feed := &feeds.Feed{ + Title: profile.Name, + Link: &feeds.Link{Href: baseURL}, + Description: profile.Description, + Created: time.Now(), + } + + feed.Items = make([]*feeds.Item, len(memoList)) + for i, memo := range memoList { + var useTitle = strings.HasPrefix(memo.Content, "# ") + + var title string + if useTitle { + title = strings.Split(memo.Content, "\n")[0][2:] + } else { + title = memo.Creator.Username + "-memos-" + strconv.Itoa(memo.ID) + } + + var description string + if useTitle { + var firstLineEnd = strings.Index(memo.Content, "\n") + description = memo.Content[firstLineEnd+1:] + } else { + description = memo.Content + } + + feed.Items[i] = &feeds.Item{ + Title: title, + Link: &feeds.Link{Href: baseURL + "/m/" + strconv.Itoa(memo.ID)}, + Description: description, + Created: time.Unix(memo.CreatedTs, 0), + } + } + + rss, err := feed.ToRss() + if err != nil { + return "", err + } + return rss, nil +} + func getSystemCustomizedProfile(ctx context.Context, s *Server) (api.CustomizedProfile, error) { systemStatus := api.SystemStatus{ CustomizedProfile: api.CustomizedProfile{ diff --git a/store/cache.go b/store/cache.go index efcf5d6f..dcb0958e 100644 --- a/store/cache.go +++ b/store/cache.go @@ -1,82 +1,15 @@ package store import ( - "bytes" - "encoding/binary" - "encoding/gob" "fmt" - "github.com/VictoriaMetrics/fastcache" + "github.com/usememos/memos/api" ) -var ( - // 64 MiB. - cacheSize = 1024 * 1024 * 64 -) - -// CacheService implements a cache. -type CacheService struct { - cache *fastcache.Cache +func getUserSettingCacheKey(userSetting userSettingRaw) string { + return fmt.Sprintf("%d-%s", userSetting.UserID, userSetting.Key.String()) } -// CacheNamespace is the type of a cache. -type CacheNamespace string - -const ( - // UserCache is the cache type of users. - UserCache CacheNamespace = "u" - // MemoCache is the cache type of memos. - MemoCache CacheNamespace = "m" - // ShortcutCache is the cache type of shortcuts. - ShortcutCache CacheNamespace = "s" -) - -// 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 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 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 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...)) - } +func getUserSettingFindCacheKey(userSettingFind *api.UserSettingFind) string { + return fmt.Sprintf("%d-%s", userSettingFind.UserID, userSettingFind.Key.String()) } diff --git a/store/memo.go b/store/memo.go index 4b70d14e..4b1900be 100644 --- a/store/memo.go +++ b/store/memo.go @@ -25,6 +25,7 @@ type memoRaw struct { // Domain specific fields Content string Visibility api.Visibility + Pinned bool } // toMemo creates an instance of Memo based on the memoRaw. @@ -43,24 +44,15 @@ func (raw *memoRaw) toMemo() *api.Memo { Content: raw.Content, Visibility: raw.Visibility, DisplayTs: raw.CreatedTs, + Pinned: raw.Pinned, } } func (s *Store) ComposeMemo(ctx context.Context, memo *api.Memo) (*api.Memo, error) { - memoOrganizer, err := s.FindMemoOrganizer(ctx, &api.MemoOrganizerFind{ - MemoID: memo.ID, - UserID: memo.CreatorID, - }) - if err != nil && common.ErrorCode(err) != common.NotFound { - return nil, err - } else if memoOrganizer != nil { - memo.Pinned = memoOrganizer.Pinned - } - - if err = s.ComposeMemoCreator(ctx, memo); err != nil { + if err := s.ComposeMemoCreator(ctx, memo); err != nil { return nil, err } - if err = s.ComposeMemoResourceList(ctx, memo); err != nil { + if err := s.ComposeMemoResourceList(ctx, memo); err != nil { return nil, err } @@ -102,10 +94,7 @@ func (s *Store) CreateMemo(ctx context.Context, create *api.MemoCreate) (*api.Me return nil, FormatError(err) } - if err := s.cache.UpsertCache(MemoCache, memoRaw.ID, memoRaw); err != nil { - return nil, err - } - + s.memoCache.Store(memoRaw.ID, memoRaw) memo, err := s.ComposeMemo(ctx, memoRaw.toMemo()) if err != nil { return nil, err @@ -130,10 +119,7 @@ func (s *Store) PatchMemo(ctx context.Context, patch *api.MemoPatch) (*api.Memo, return nil, FormatError(err) } - if err := s.cache.UpsertCache(MemoCache, memoRaw.ID, memoRaw); err != nil { - return nil, err - } - + s.memoCache.Store(memoRaw.ID, memoRaw) memo, err := s.ComposeMemo(ctx, memoRaw.toMemo()) if err != nil { return nil, err @@ -169,12 +155,8 @@ func (s *Store) FindMemoList(ctx context.Context, find *api.MemoFind) ([]*api.Me func (s *Store) FindMemo(ctx context.Context, find *api.MemoFind) (*api.Memo, error) { if find.ID != nil { - memoRaw := &memoRaw{} - has, err := s.cache.FindCache(MemoCache, *find.ID, memoRaw) - if err != nil { - return nil, err - } - if has { + if memo, ok := s.memoCache.Load(*find.ID); ok { + memoRaw := memo.(*memoRaw) memo, err := s.ComposeMemo(ctx, memoRaw.toMemo()) if err != nil { return nil, err @@ -199,10 +181,7 @@ func (s *Store) FindMemo(ctx context.Context, find *api.MemoFind) (*api.Memo, er } memoRaw := list[0] - if err := s.cache.UpsertCache(MemoCache, memoRaw.ID, memoRaw); err != nil { - return nil, err - } - + s.memoCache.Store(memoRaw.ID, memoRaw) memo, err := s.ComposeMemo(ctx, memoRaw.toMemo()) if err != nil { return nil, err @@ -229,8 +208,7 @@ func (s *Store) DeleteMemo(ctx context.Context, delete *api.MemoDelete) error { return FormatError(err) } - s.cache.DeleteCache(MemoCache, delete.ID) - + s.memoCache.Delete(delete.ID) return nil } @@ -309,19 +287,19 @@ func findMemoRawList(ctx context.Context, tx *sql.Tx, find *api.MemoFind) ([]*me where, args := []string{"1 = 1"}, []interface{}{} if v := find.ID; v != nil { - where, args = append(where, "id = ?"), append(args, *v) + where, args = append(where, "memo.id = ?"), append(args, *v) } if v := find.CreatorID; v != nil { - where, args = append(where, "creator_id = ?"), append(args, *v) + where, args = append(where, "memo.creator_id = ?"), append(args, *v) } if v := find.RowStatus; v != nil { - where, args = append(where, "row_status = ?"), append(args, *v) + where, args = append(where, "memo.row_status = ?"), append(args, *v) } if v := find.Pinned; v != nil { - where = append(where, "id IN (SELECT memo_id FROM memo_organizer WHERE pinned = 1 AND user_id = memo.creator_id)") + where = append(where, "memo_organizer.pinned = 1") } if v := find.ContentSearch; v != nil { - where, args = append(where, "content LIKE ?"), append(args, "%"+*v+"%") + where, args = append(where, "memo.content LIKE ?"), append(args, "%"+*v+"%") } if v := find.VisibilityList; len(v) != 0 { list := []string{} @@ -329,21 +307,23 @@ func findMemoRawList(ctx context.Context, tx *sql.Tx, find *api.MemoFind) ([]*me list = append(list, fmt.Sprintf("$%d", len(args)+1)) args = append(args, visibility) } - where = append(where, fmt.Sprintf("visibility in (%s)", strings.Join(list, ","))) + where = append(where, fmt.Sprintf("memo.visibility in (%s)", strings.Join(list, ","))) } query := ` SELECT - id, - creator_id, - created_ts, - updated_ts, - row_status, - content, - visibility + memo.id, + memo.creator_id, + memo.created_ts, + memo.updated_ts, + memo.row_status, + memo.content, + memo.visibility, + memo_organizer.pinned FROM memo + LEFT JOIN memo_organizer ON memo_organizer.memo_id = memo.id WHERE ` + strings.Join(where, " AND ") + ` - ORDER BY created_ts DESC + ORDER BY memo.created_ts DESC ` rows, err := tx.QueryContext(ctx, query, args...) if err != nil { @@ -354,6 +334,7 @@ func findMemoRawList(ctx context.Context, tx *sql.Tx, find *api.MemoFind) ([]*me memoRawList := make([]*memoRaw, 0) for rows.Next() { var memoRaw memoRaw + var pinned sql.NullBool if err := rows.Scan( &memoRaw.ID, &memoRaw.CreatorID, @@ -362,10 +343,14 @@ func findMemoRawList(ctx context.Context, tx *sql.Tx, find *api.MemoFind) ([]*me &memoRaw.RowStatus, &memoRaw.Content, &memoRaw.Visibility, + &pinned, ); err != nil { return nil, FormatError(err) } + if pinned.Valid { + memoRaw.Pinned = pinned.Bool + } memoRawList = append(memoRawList, &memoRaw) } diff --git a/store/shortcut.go b/store/shortcut.go index 7a81d17b..5348097f 100644 --- a/store/shortcut.go +++ b/store/shortcut.go @@ -56,10 +56,7 @@ func (s *Store) CreateShortcut(ctx context.Context, create *api.ShortcutCreate) return nil, FormatError(err) } - if err := s.cache.UpsertCache(ShortcutCache, shortcutRaw.ID, shortcutRaw); err != nil { - return nil, err - } - + s.shortcutCache.Store(shortcutRaw.ID, shortcutRaw) shortcut := shortcutRaw.toShortcut() return shortcut, nil @@ -81,10 +78,7 @@ func (s *Store) PatchShortcut(ctx context.Context, patch *api.ShortcutPatch) (*a return nil, FormatError(err) } - if err := s.cache.UpsertCache(ShortcutCache, shortcutRaw.ID, shortcutRaw); err != nil { - return nil, err - } - + s.shortcutCache.Store(shortcutRaw.ID, shortcutRaw) shortcut := shortcutRaw.toShortcut() return shortcut, nil @@ -112,13 +106,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 { - shortcutRaw := &shortcutRaw{} - has, err := s.cache.FindCache(ShortcutCache, *find.ID, shortcutRaw) - if err != nil { - return nil, err - } - if has { - return shortcutRaw.toShortcut(), nil + if shortcut, ok := s.shortcutCache.Load(*find.ID); ok { + return shortcut.(*shortcutRaw).toShortcut(), nil } } @@ -138,11 +127,7 @@ func (s *Store) FindShortcut(ctx context.Context, find *api.ShortcutFind) (*api. } shortcutRaw := list[0] - - if err := s.cache.UpsertCache(ShortcutCache, shortcutRaw.ID, shortcutRaw); err != nil { - return nil, err - } - + s.shortcutCache.Store(shortcutRaw.ID, shortcutRaw) shortcut := shortcutRaw.toShortcut() return shortcut, nil @@ -164,8 +149,7 @@ func (s *Store) DeleteShortcut(ctx context.Context, delete *api.ShortcutDelete) return FormatError(err) } - s.cache.DeleteCache(ShortcutCache, *delete.ID) - + s.shortcutCache.Delete(*delete.ID) return nil } diff --git a/store/store.go b/store/store.go index 8d9b3e0b..f4a3ae02 100644 --- a/store/store.go +++ b/store/store.go @@ -3,6 +3,7 @@ package store import ( "context" "database/sql" + "sync" "github.com/usememos/memos/server/profile" ) @@ -11,17 +12,18 @@ import ( type Store struct { db *sql.DB profile *profile.Profile - cache *CacheService + + userCache sync.Map // map[int]*userRaw + userSettingCache sync.Map // map[string]*userSettingRaw + memoCache 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, } } diff --git a/store/user.go b/store/user.go index 0bf3288d..bee8a0c0 100644 --- a/store/user.go +++ b/store/user.go @@ -58,10 +58,8 @@ func (s *Store) ComposeMemoCreator(ctx context.Context, memo *api.Memo) error { user.OpenID = "" user.UserSettingList = nil memo.Creator = user - return nil } - func (s *Store) CreateUser(ctx context.Context, create *api.UserCreate) (*api.User, error) { tx, err := s.db.BeginTx(ctx, nil) if err != nil { @@ -78,12 +76,8 @@ func (s *Store) CreateUser(ctx context.Context, create *api.UserCreate) (*api.Us return nil, FormatError(err) } - if err := s.cache.UpsertCache(UserCache, userRaw.ID, userRaw); err != nil { - return nil, err - } - + s.userCache.Store(userRaw.ID, userRaw) user := userRaw.toUser() - return user, nil } @@ -103,12 +97,8 @@ func (s *Store) PatchUser(ctx context.Context, patch *api.UserPatch) (*api.User, return nil, FormatError(err) } - if err := s.cache.UpsertCache(UserCache, userRaw.ID, userRaw); err != nil { - return nil, err - } - + s.userCache.Store(userRaw.ID, userRaw) user := userRaw.toUser() - return user, nil } @@ -134,13 +124,8 @@ func (s *Store) FindUserList(ctx context.Context, find *api.UserFind) ([]*api.Us func (s *Store) FindUser(ctx context.Context, find *api.UserFind) (*api.User, error) { if find.ID != nil { - userRaw := &userRaw{} - has, err := s.cache.FindCache(UserCache, *find.ID, userRaw) - if err != nil { - return nil, err - } - if has { - return userRaw.toUser(), nil + if user, ok := s.userCache.Load(*find.ID); ok { + return user.(*userRaw).toUser(), nil } } @@ -160,13 +145,8 @@ func (s *Store) FindUser(ctx context.Context, find *api.UserFind) (*api.User, er } userRaw := list[0] - - if err := s.cache.UpsertCache(UserCache, userRaw.ID, userRaw); err != nil { - return nil, err - } - + s.userCache.Store(userRaw.ID, userRaw) user := userRaw.toUser() - return user, nil } @@ -188,8 +168,7 @@ func (s *Store) DeleteUser(ctx context.Context, delete *api.UserDelete) error { return err } - s.cache.DeleteCache(UserCache, delete.ID) - + s.userCache.Delete(delete.ID) return nil } diff --git a/store/user_setting.go b/store/user_setting.go index 7e2a7f35..64f14b05 100644 --- a/store/user_setting.go +++ b/store/user_setting.go @@ -38,6 +38,7 @@ func (s *Store) UpsertUserSetting(ctx context.Context, upsert *api.UserSettingUp return nil, err } + s.userSettingCache.Store(getUserSettingCacheKey(*userSettingRaw), userSettingRaw) userSetting := userSettingRaw.toUserSetting() return userSetting, nil @@ -57,6 +58,7 @@ func (s *Store) FindUserSettingList(ctx context.Context, find *api.UserSettingFi list := []*api.UserSetting{} for _, raw := range userSettingRawList { + s.userSettingCache.Store(getUserSettingCacheKey(*raw), raw) list = append(list, raw.toUserSetting()) } @@ -64,6 +66,13 @@ func (s *Store) FindUserSettingList(ctx context.Context, find *api.UserSettingFi } func (s *Store) FindUserSetting(ctx context.Context, find *api.UserSettingFind) (*api.UserSetting, error) { + if userSetting, ok := s.userSettingCache.Load(getUserSettingFindCacheKey(find)); ok { + if userSetting == nil { + return nil, nil + } + return userSetting.(*userSettingRaw).toUserSetting(), nil + } + tx, err := s.db.BeginTx(ctx, nil) if err != nil { return nil, FormatError(err) @@ -76,12 +85,13 @@ func (s *Store) FindUserSetting(ctx context.Context, find *api.UserSettingFind) } if len(list) == 0 { + s.userSettingCache.Store(getUserSettingFindCacheKey(find), nil) return nil, nil } - userSetting := list[0].toUserSetting() - - return userSetting, nil + userSettingRaw := list[0] + s.userSettingCache.Store(getUserSettingCacheKey(*userSettingRaw), userSettingRaw) + return userSettingRaw.toUserSetting(), nil } func upsertUserSetting(ctx context.Context, tx *sql.Tx, upsert *api.UserSettingUpsert) (*userSettingRaw, error) {