add cache support for GetUserTweets api

pull/385/head
Michael Li 10 months ago
parent 8ca3c72467
commit 66d7779ce6
No known key found for this signature in database

@ -89,7 +89,12 @@ func RegisterLooseServant(e *gin.Engine, s Loose) {
return
}
resp, err := s.GetUserTweets(req)
s.Render(c, resp, err)
if err != nil {
s.Render(c, nil, err)
return
}
var rv _render_ = resp
rv.Render(c)
})
router.Handle("GET", "/posts", func(c *gin.Context) {
select {

@ -14,6 +14,11 @@ const (
_defaultKeyPoolSize = 128
)
// 以下包含一些在cache中会用到的key的前缀
const (
PrefixUserTweets = "paopao:usertweets:"
)
// 以下包含一些在cache中会用到的池化后的key
var (
KeyUnreadMsg cache.KeyPool[int64]

@ -9,6 +9,7 @@ Cache:
KeyPoolSize: 256 # 键的池大小, 设置范围[128, ++], 默认256
CientSideCacheExpire: 60 # 客户端缓存过期时间 默认60s
UnreadMsgExpire: 60 # 未读消息过期时间,单位秒, 默认60s
UserTweetsExpire: 60 # 获取用户推文列表过期时间,单位秒, 默认60s
EventManager: # 事件管理器的配置参数
MinWorker: 10 # 最小后台工作者, 设置范围[5, ++], 默认10
MaxEventBuf: 100 # 最大log缓存条数, 设置范围[10, ++], 默认100

@ -100,6 +100,7 @@ type cacheConf struct {
KeyPoolSize int
CientSideCacheExpire time.Duration
UnreadMsgExpire int64
UserTweetsExpire int64
}
type eventManagerConf struct {

@ -103,6 +103,7 @@ type AppCache interface {
Set(key string, data []byte, ex int64) error
Delete(key ...string) error
DelAny(pattern string) error
Exist(key string) bool
}
type WebCache interface {

@ -79,6 +79,12 @@ func (s *appCache) DelAny(pattern string) (err error) {
return
}
func (s *appCache) Exist(key string) bool {
cmd := s.c.B().Exists().Key(key).Build()
count, _ := s.c.Do(context.Background(), cmd).AsInt64()
return count > 0
}
func (s *webCache) GetUnreadMsgCountResp(uid int64) ([]byte, error) {
key := conf.KeyUnreadMsg.Get(uid)
return s.Get(key)

@ -5,10 +5,14 @@
package web
import (
"encoding/json"
"net/http"
"github.com/alimy/mir/v4"
"github.com/gin-gonic/gin"
"github.com/rocboss/paopao-ce/internal/core"
"github.com/rocboss/paopao-ce/internal/core/cs"
"github.com/rocboss/paopao-ce/internal/model/joint"
"github.com/rocboss/paopao-ce/internal/servants/base"
"github.com/rocboss/paopao-ce/pkg/app"
)
@ -59,7 +63,10 @@ type GetUserTweetsReq struct {
PageSize int `form:"-" binding:"-"`
}
type GetUserTweetsResp base.PageResp
type GetUserTweetsResp struct {
Data *base.PageResp
JsonResp json.RawMessage
}
type GetUserProfileReq struct {
BaseInfo `form:"-" binding:"-"`
@ -111,3 +118,15 @@ func (r *TimelineReq) Bind(c *gin.Context) mir.Error {
r.Query, r.Type = c.Query("query"), "search"
return nil
}
func (r *GetUserTweetsResp) Render(c *gin.Context) {
if len(r.JsonResp) != 0 {
c.JSON(http.StatusOK, r.JsonResp)
} else {
c.JSON(http.StatusOK, &joint.JsonResp{
Code: 0,
Msg: "success",
Data: r.Data,
})
}
}

@ -5,9 +5,13 @@
package web
import (
"fmt"
"github.com/alimy/mir/v4"
"github.com/alimy/tryst/lets"
"github.com/gin-gonic/gin"
api "github.com/rocboss/paopao-ce/auto/api/v1"
"github.com/rocboss/paopao-ce/internal/conf"
"github.com/rocboss/paopao-ce/internal/core"
"github.com/rocboss/paopao-ce/internal/core/cs"
"github.com/rocboss/paopao-ce/internal/core/ms"
@ -25,6 +29,9 @@ var (
type looseSrv struct {
api.UnimplementedLooseServant
*base.DaoServant
ac core.AppCache
userTweetsExpire int64
prefixUserTweets string
}
func (s *looseSrv) Chain() gin.HandlersChain {
@ -66,6 +73,13 @@ func (s *looseSrv) GetUserTweets(req *web.GetUserTweetsReq) (res *web.GetUserTwe
if xerr != nil {
return nil, err
}
// 尝试直接从缓存中获取数据
key, ok := "", false
if res, key, ok = s.userTweetsFromCache(req, user); ok {
// logrus.Debugf("GetUserTweets from cache key:%s", key)
return
}
// 缓存获取未成功,只能查库了
switch req.Style {
case web.UserPostsStyleComment, web.UserPostsStyleMedia:
res, err = s.listUserTweets(req, user)
@ -78,6 +92,28 @@ func (s *looseSrv) GetUserTweets(req *web.GetUserTweetsReq) (res *web.GetUserTwe
default:
res, err = s.getUserPostTweets(req, user, false)
}
// 缓存处理
if err == nil {
if xerr == nil {
base.OnCacheRespEvent(s.ac, key, res.Data, s.userTweetsExpire)
} else {
logrus.Warnf("marshal user tweets response to json occurs error: %s", xerr)
}
}
return
}
func (s *looseSrv) userTweetsFromCache(req *web.GetUserTweetsReq, user *cs.VistUser) (res *web.GetUserTweetsResp, key string, ok bool) {
switch req.Style {
case web.UserPostsStylePost, web.UserPostsStyleHighlight, web.UserPostsStyleMedia:
key = fmt.Sprintf("%s%s:%s:%s:%d:%d", s.prefixUserTweets, req.Username, req.Style, user.RelTyp, req.Page, req.PageSize)
default:
visitUserName := lets.If(user.RelTyp != cs.RelationGuest, user.Username, "_")
key = fmt.Sprintf("%s%s:%s:%s:%d:%d", s.prefixUserTweets, req.Username, req.Style, visitUserName, req.Page, req.PageSize)
}
if data, err := s.ac.Get(key); err == nil {
ok, res = true, &web.GetUserTweetsResp{JsonResp: data}
}
return
}
@ -99,7 +135,7 @@ func (s *looseSrv) getUserStarTweets(req *web.GetUserTweetsReq, user *cs.VistUse
return nil, web.ErrGetStarsFailed
}
resp := base.PageRespFrom(postsFormated, req.Page, req.PageSize, totalRows)
return (*web.GetUserTweetsResp)(resp), nil
return &web.GetUserTweetsResp{Data: resp}, nil
}
func (s *looseSrv) listUserTweets(req *web.GetUserTweetsReq, user *cs.VistUser) (*web.GetUserTweetsResp, mir.Error) {
@ -126,7 +162,7 @@ func (s *looseSrv) listUserTweets(req *web.GetUserTweetsReq, user *cs.VistUser)
return nil, web.ErrGetPostsFailed
}
resp := base.PageRespFrom(postFormated, req.Page, req.PageSize, total)
return (*web.GetUserTweetsResp)(resp), nil
return &web.GetUserTweetsResp{Data: resp}, nil
}
func (s *looseSrv) getUserPostTweets(req *web.GetUserTweetsReq, user *cs.VistUser, isHighlight bool) (*web.GetUserTweetsResp, mir.Error) {
@ -160,7 +196,7 @@ func (s *looseSrv) getUserPostTweets(req *web.GetUserTweetsReq, user *cs.VistUse
return nil, web.ErrGetPostsFailed
}
resp := base.PageRespFrom(posts, req.Page, req.PageSize, totalRows)
return (*web.GetUserTweetsResp)(resp), nil
return &web.GetUserTweetsResp{Data: resp}, nil
}
func (s *looseSrv) GetUserProfile(req *web.GetUserProfileReq) (*web.GetUserProfileResp, mir.Error) {
@ -322,8 +358,11 @@ func (s *looseSrv) TweetComments(req *web.TweetCommentsReq) (*web.TweetCommentsR
return (*web.TweetCommentsResp)(resp), nil
}
func newLooseSrv(s *base.DaoServant) api.Loose {
func newLooseSrv(s *base.DaoServant, ac core.AppCache) api.Loose {
return &looseSrv{
DaoServant: s,
DaoServant: s,
ac: ac,
userTweetsExpire: conf.CacheSetting.UserTweetsExpire,
prefixUserTweets: conf.PrefixUserTweets,
}
}

@ -21,6 +21,7 @@ var (
_enablePhoneVerify bool
_disallowUserRegister bool
_ds core.DataService
_ac core.AppCache
_wc core.WebCache
_oss core.ObjectStorageService
_onceInitial sync.Once
@ -34,7 +35,7 @@ func RouteWeb(e *gin.Engine) {
api.RegisterAdminServant(e, newAdminSrv(ds))
api.RegisterCoreServant(e, newCoreSrv(ds, _oss, _wc))
api.RegisterRelaxServant(e, newRelaxSrv(ds, _wc))
api.RegisterLooseServant(e, newLooseSrv(ds))
api.RegisterLooseServant(e, newLooseSrv(ds, _ac))
api.RegisterPrivServant(e, newPrivSrv(ds, _oss))
api.RegisterPubServant(e, newPubSrv(ds))
api.RegisterFollowshipServant(e, newFollowshipSrv(ds))
@ -54,6 +55,7 @@ func lazyInitial() {
_disallowUserRegister = cfg.If("Web:DisallowUserRegister")
_oss = dao.ObjectStorageService()
_ds = dao.DataService()
_ac = cache.NewAppCache()
_wc = cache.NewWebCache()
})
}

Loading…
Cancel
Save