fix bug 及缓存调整

This commit is contained in:
xing 2023-01-20 18:10:13 +08:00
parent 3f4396fb02
commit e780c358d7
8 changed files with 81 additions and 70 deletions

View File

@ -9,26 +9,26 @@ import (
"time" "time"
) )
type SliceCache[T any] struct { type VarCache[T any] struct {
v safety.Var[slice[T]] v safety.Var[vars[T]]
} }
type slice[T any] struct { type vars[T any] struct {
data []T data T
mutex *sync.Mutex mutex *sync.Mutex
setCacheFunc func(...any) ([]T, error) setCacheFunc func(...any) (T, error)
expireTime time.Duration expireTime time.Duration
setTime time.Time setTime time.Time
incr int incr int
} }
func (c *SliceCache[T]) GetLastSetTime() time.Time { func (c *VarCache[T]) GetLastSetTime() time.Time {
return c.v.Load().setTime return c.v.Load().setTime
} }
func NewSliceCache[T any](fun func(...any) ([]T, error), duration time.Duration) *SliceCache[T] { func NewVarCache[T any](fun func(...any) (T, error), duration time.Duration) *VarCache[T] {
return &SliceCache[T]{ return &VarCache[T]{
v: safety.NewVar(slice[T]{ v: safety.NewVar(vars[T]{
mutex: &sync.Mutex{}, mutex: &sync.Mutex{},
setCacheFunc: fun, setCacheFunc: fun,
expireTime: duration, expireTime: duration,
@ -36,20 +36,23 @@ func NewSliceCache[T any](fun func(...any) ([]T, error), duration time.Duration)
} }
} }
func (c *SliceCache[T]) FlushCache() { func (c *VarCache[T]) IsExpired() bool {
v := c.v.Load()
return time.Duration(v.setTime.UnixNano())+v.expireTime < time.Duration(time.Now().UnixNano())
}
func (c *VarCache[T]) Flush() {
mu := c.v.Load().mutex mu := c.v.Load().mutex
mu.Lock() mu.Lock()
defer mu.Unlock() defer mu.Unlock()
c.v.Delete() c.v.Delete()
} }
func (c *SliceCache[T]) GetCache(ctx context.Context, timeout time.Duration, params ...any) ([]T, error) { func (c *VarCache[T]) GetCache(ctx context.Context, timeout time.Duration, params ...any) (T, error) {
v := c.v.Load() v := c.v.Load()
l := len(v.data)
data := v.data data := v.data
var err error var err error
expired := time.Duration(v.setTime.UnixNano())+v.expireTime < time.Duration(time.Now().UnixNano()) if v.expireTime <= 0 || ((time.Duration(v.setTime.UnixNano()) + v.expireTime) < time.Duration(time.Now().UnixNano())) {
if l < 1 || (l > 0 && v.expireTime >= 0 && expired) {
t := v.incr t := v.incr
call := func() { call := func() {
v.mutex.Lock() v.mutex.Lock()

View File

@ -10,13 +10,10 @@ import (
"github.com/fthvgb1/wp-go/internal/wpconfig" "github.com/fthvgb1/wp-go/internal/wpconfig"
"github.com/gin-contrib/sessions" "github.com/gin-contrib/sessions"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"math/rand"
"net/http" "net/http"
"net/url"
"sort" "sort"
"strconv" "strconv"
"strings" "strings"
"time"
) )
type detailHandler struct { type detailHandler struct {
@ -68,7 +65,7 @@ func Detail(c *gin.Context) {
return return
} }
post, err := cache.GetPostById(c, ID) post, err := cache.GetPostById(c, ID)
if post.Id == 0 || err != nil { if post.Id == 0 || err != nil || post.PostStatus != "publish" {
return return
} }
pw := sessions.Default(c).Get("post_password") pw := sessions.Default(c).Get("post_password")
@ -244,7 +241,7 @@ func (d detailHandler) formatLi(comments models.Comments, depth int, eo, parent
for k, v := range map[string]string{ for k, v := range map[string]string{
"{{CommentId}}": strconv.FormatUint(comments.CommentId, 10), "{{CommentId}}": strconv.FormatUint(comments.CommentId, 10),
"{{Depth}}": strconv.Itoa(depth), "{{Depth}}": strconv.Itoa(depth),
"{{Gravatar}}": gravatar(d.Context, comments.CommentAuthorEmail), "{{Gravatar}}": plugins.Gravatar(comments.CommentAuthorEmail, d.Context.Request.TLS != nil),
"{{CommentAuthorUrl}}": comments.CommentAuthorUrl, "{{CommentAuthorUrl}}": comments.CommentAuthorUrl,
"{{CommentAuthor}}": comments.CommentAuthor, "{{CommentAuthor}}": comments.CommentAuthor,
"{{PostId}}": strconv.FormatUint(comments.CommentPostId, 10), "{{PostId}}": strconv.FormatUint(comments.CommentPostId, 10),
@ -258,25 +255,3 @@ func (d detailHandler) formatLi(comments models.Comments, depth int, eo, parent
} }
return li return li
} }
func gravatar(c *gin.Context, email string) (u string) {
email = strings.Trim(email, " \t\n\r\000\x0B")
rand.Seed(time.Now().UnixNano())
num := rand.Intn(3)
h := ""
if email != "" {
h = helper.StringMd5(strings.ToLower(email))
num = int(h[0] % 3)
}
if c.Request.TLS != nil {
u = fmt.Sprintf("%s%s", "https://secure.gravatar.com/avatar/", h)
} else {
u = fmt.Sprintf("http://%d.gravatar.com/avatar/%s", num, h)
}
q := url.Values{}
q.Add("s", "112")
q.Add("d", "mm")
q.Add("r", strings.ToLower(wpconfig.Options.Value("avatar_rating")))
u = fmt.Sprintf("%s?%s", u, q.Encode())
return
}

View File

@ -13,9 +13,9 @@ import (
var postContextCache *cache.MapCache[uint64, common.PostContext] var postContextCache *cache.MapCache[uint64, common.PostContext]
var archivesCaches *Arch var archivesCaches *Arch
var categoryCaches *cache.SliceCache[models.TermsMy] var categoryCaches *cache.VarCache[[]models.TermsMy]
var recentPostsCaches *cache.SliceCache[models.Posts] var recentPostsCaches *cache.VarCache[[]models.Posts]
var recentCommentsCaches *cache.SliceCache[models.Comments] var recentCommentsCaches *cache.VarCache[[]models.Comments]
var postCommentCaches *cache.MapCache[uint64, []uint64] var postCommentCaches *cache.MapCache[uint64, []uint64]
var postsCache *cache.MapCache[uint64, models.Posts] var postsCache *cache.MapCache[uint64, models.Posts]
@ -24,17 +24,17 @@ var postMetaCache *cache.MapCache[uint64, map[string]any]
var monthPostsCache *cache.MapCache[string, []uint64] var monthPostsCache *cache.MapCache[string, []uint64]
var postListIdsCache *cache.MapCache[string, common.PostIds] var postListIdsCache *cache.MapCache[string, common.PostIds]
var searchPostIdsCache *cache.MapCache[string, common.PostIds] var searchPostIdsCache *cache.MapCache[string, common.PostIds]
var maxPostIdCache *cache.SliceCache[uint64] var maxPostIdCache *cache.VarCache[uint64]
var usersCache *cache.MapCache[uint64, models.Users] var usersCache *cache.MapCache[uint64, models.Users]
var usersNameCache *cache.MapCache[string, models.Users] var usersNameCache *cache.MapCache[string, models.Users]
var commentsCache *cache.MapCache[uint64, models.Comments] var commentsCache *cache.MapCache[uint64, models.Comments]
var feedCache *cache.SliceCache[string] var feedCache *cache.VarCache[[]string]
var postFeedCache *cache.MapCache[string, string] var postFeedCache *cache.MapCache[string, string]
var commentsFeedCache *cache.SliceCache[string] var commentsFeedCache *cache.VarCache[[]string]
var newCommentCache *cache.MapCache[string, string] var newCommentCache *cache.MapCache[string, string]
@ -45,39 +45,39 @@ func InitActionsCommonCache() {
setCacheFunc: common.Archives, setCacheFunc: common.Archives,
} }
searchPostIdsCache = cache.NewMapCacheByFn[string, common.PostIds](common.SearchPostIds, c.SearchPostCacheTime) searchPostIdsCache = cache.NewMapCacheByFn[string](common.SearchPostIds, c.SearchPostCacheTime)
postListIdsCache = cache.NewMapCacheByFn[string, common.PostIds](common.SearchPostIds, c.PostListCacheTime) postListIdsCache = cache.NewMapCacheByFn[string](common.SearchPostIds, c.PostListCacheTime)
monthPostsCache = cache.NewMapCacheByFn[string, []uint64](common.MonthPost, c.MonthPostCacheTime) monthPostsCache = cache.NewMapCacheByFn[string](common.MonthPost, c.MonthPostCacheTime)
postContextCache = cache.NewMapCacheByFn[uint64, common.PostContext](common.GetPostContext, c.ContextPostCacheTime) postContextCache = cache.NewMapCacheByFn[uint64](common.GetPostContext, c.ContextPostCacheTime)
postsCache = cache.NewMapCacheByBatchFn[uint64, models.Posts](common.GetPostsByIds, c.PostDataCacheTime) postsCache = cache.NewMapCacheByBatchFn(common.GetPostsByIds, c.PostDataCacheTime)
postMetaCache = cache.NewMapCacheByBatchFn[uint64, map[string]any](common.GetPostMetaByPostIds, c.PostDataCacheTime) postMetaCache = cache.NewMapCacheByBatchFn(common.GetPostMetaByPostIds, c.PostDataCacheTime)
categoryCaches = cache.NewSliceCache[models.TermsMy](common.Categories, c.CategoryCacheTime) categoryCaches = cache.NewVarCache(common.Categories, c.CategoryCacheTime)
recentPostsCaches = cache.NewSliceCache[models.Posts](common.RecentPosts, c.RecentPostCacheTime) recentPostsCaches = cache.NewVarCache(common.RecentPosts, c.RecentPostCacheTime)
recentCommentsCaches = cache.NewSliceCache[models.Comments](common.RecentComments, c.RecentCommentsCacheTime) recentCommentsCaches = cache.NewVarCache(common.RecentComments, c.RecentCommentsCacheTime)
postCommentCaches = cache.NewMapCacheByFn[uint64, []uint64](common.PostComments, c.PostCommentsCacheTime) postCommentCaches = cache.NewMapCacheByFn[uint64](common.PostComments, c.PostCommentsCacheTime)
maxPostIdCache = cache.NewSliceCache[uint64](common.GetMaxPostId, c.MaxPostIdCacheTime) maxPostIdCache = cache.NewVarCache(common.GetMaxPostId, c.MaxPostIdCacheTime)
usersCache = cache.NewMapCacheByFn[uint64, models.Users](common.GetUserById, c.UserInfoCacheTime) usersCache = cache.NewMapCacheByFn[uint64](common.GetUserById, c.UserInfoCacheTime)
usersNameCache = cache.NewMapCacheByFn[string, models.Users](common.GetUserByName, c.UserInfoCacheTime) usersNameCache = cache.NewMapCacheByFn[string](common.GetUserByName, c.UserInfoCacheTime)
commentsCache = cache.NewMapCacheByBatchFn[uint64, models.Comments](common.GetCommentByIds, c.CommentsCacheTime) commentsCache = cache.NewMapCacheByBatchFn(common.GetCommentByIds, c.CommentsCacheTime)
feedCache = cache.NewSliceCache(feed, time.Hour) feedCache = cache.NewVarCache(feed, time.Hour)
postFeedCache = cache.NewMapCacheByFn[string, string](postFeed, time.Hour) postFeedCache = cache.NewMapCacheByFn[string](postFeed, time.Hour)
commentsFeedCache = cache.NewSliceCache(commentsFeed, time.Hour) commentsFeedCache = cache.NewVarCache(commentsFeed, time.Hour)
newCommentCache = cache.NewMapCacheByFn[string, string](nil, 15*time.Minute) newCommentCache = cache.NewMapCacheByFn[string, string](nil, 15*time.Minute)

View File

@ -32,11 +32,11 @@ func InitFeed() {
} }
} }
func CommentsFeedCache() *cache.SliceCache[string] { func CommentsFeedCache() *cache.VarCache[[]string] {
return commentsFeedCache return commentsFeedCache
} }
func FeedCache() *cache.SliceCache[string] { func FeedCache() *cache.VarCache[[]string] {
return feedCache return feedCache
} }

View File

@ -39,8 +39,7 @@ func PostLists(ctx context.Context, key string, args ...any) (r []models.Posts,
} }
func GetMaxPostId(ctx *gin.Context) (uint64, error) { func GetMaxPostId(ctx *gin.Context) (uint64, error) {
Id, err := maxPostIdCache.GetCache(ctx, time.Second, ctx) return maxPostIdCache.GetCache(ctx, time.Second, ctx)
return Id[0], err
} }
func RecentPosts(ctx context.Context, n int) (r []models.Posts) { func RecentPosts(ctx context.Context, n int) (r []models.Posts) {

View File

@ -109,14 +109,14 @@ func SearchPostIds(args ...any) (ids PostIds, err error) {
return return
} }
func GetMaxPostId(a ...any) ([]uint64, error) { func GetMaxPostId(a ...any) (uint64, error) {
ctx := a[0].(context.Context) ctx := a[0].(context.Context)
r, err := model.SimpleFind[models.Posts](ctx, model.SqlBuilder{{"post_type", "post"}, {"post_status", "publish"}}, "max(ID) ID") r, err := model.SimpleFind[models.Posts](ctx, model.SqlBuilder{{"post_type", "post"}, {"post_status", "publish"}}, "max(ID) ID")
var id uint64 var id uint64
if len(r) > 0 { if len(r) > 0 {
id = r[0].Id id = r[0].Id
} }
return []uint64{id}, err return id, err
} }
func RecentPosts(a ...any) (r []models.Posts, err error) { func RecentPosts(a ...any) (r []models.Posts, err error) {

View File

@ -0,0 +1 @@
package plugins

View File

@ -0,0 +1,33 @@
package plugins
import (
"fmt"
"github.com/fthvgb1/wp-go/helper"
"github.com/fthvgb1/wp-go/internal/wpconfig"
"math/rand"
"net/url"
"strings"
"time"
)
func Gravatar(email string, isTls bool) (u string) {
email = strings.Trim(email, " \t\n\r\000\x0B")
rand.Seed(time.Now().UnixNano())
num := rand.Intn(3)
h := ""
if email != "" {
h = helper.StringMd5(strings.ToLower(email))
num = int(h[0] % 3)
}
if isTls {
u = fmt.Sprintf("%s%s", "https://secure.gravatar.com/avatar/", h)
} else {
u = fmt.Sprintf("http://%d.gravatar.com/avatar/%s", num, h)
}
q := url.Values{}
q.Add("s", "112")
q.Add("d", "mm")
q.Add("r", strings.ToLower(wpconfig.Options.Value("avatar_rating")))
u = fmt.Sprintf("%s?%s", u, q.Encode())
return
}