抽象缓存接口
This commit is contained in:
parent
dc04b8dc2b
commit
490abf0bf6
16
cache/interface.go
vendored
Normal file
16
cache/interface.go
vendored
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
package cache
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Cache[K comparable, V any] interface {
|
||||||
|
Get(ctx context.Context, key K) (V, bool)
|
||||||
|
Set(ctx context.Context, key K, val V, expire time.Duration)
|
||||||
|
Ttl(ctx context.Context, key K, expire time.Duration) time.Duration
|
||||||
|
Ver(ctx context.Context, key K) int
|
||||||
|
Flush(ctx context.Context)
|
||||||
|
Delete(ctx context.Context, key K)
|
||||||
|
ClearExpired(ctx context.Context, expire time.Duration)
|
||||||
|
}
|
189
cache/map.go
vendored
189
cache/map.go
vendored
|
@ -4,42 +4,32 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/fthvgb1/wp-go/safety"
|
"github.com/fthvgb1/wp-go/helper/slice"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
type MapCache[K comparable, V any] struct {
|
type MapCache[K comparable, V any] struct {
|
||||||
data safety.Map[K, mapCacheStruct[V]]
|
data Cache[K, V]
|
||||||
mutex *sync.Mutex
|
mux sync.Mutex
|
||||||
cacheFunc func(...any) (V, error)
|
cacheFunc func(...any) (V, error)
|
||||||
batchCacheFn func(...any) (map[K]V, error)
|
batchCacheFn func(...any) (map[K]V, error)
|
||||||
expireTime time.Duration
|
expireTime time.Duration
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewMapCache[K comparable, V any](expireTime time.Duration) *MapCache[K, V] {
|
|
||||||
return &MapCache[K, V]{expireTime: expireTime}
|
|
||||||
}
|
|
||||||
|
|
||||||
type mapCacheStruct[T any] struct {
|
|
||||||
setTime time.Time
|
|
||||||
incr int
|
|
||||||
data T
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *MapCache[K, V]) SetCacheFunc(fn func(...any) (V, error)) {
|
func (m *MapCache[K, V]) SetCacheFunc(fn func(...any) (V, error)) {
|
||||||
m.cacheFunc = fn
|
m.cacheFunc = fn
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *MapCache[K, V]) GetLastSetTime(k K) (t time.Time) {
|
func (m *MapCache[K, V]) GetLastSetTime(ctx context.Context, k K) (t time.Time) {
|
||||||
r, ok := m.data.Load(k)
|
tt := m.data.Ttl(ctx, k, m.expireTime)
|
||||||
if ok {
|
if tt <= 0 {
|
||||||
t = r.setTime
|
|
||||||
}
|
|
||||||
return
|
return
|
||||||
|
}
|
||||||
|
return time.Now().Add(m.data.Ttl(ctx, k, m.expireTime))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *MapCache[K, V]) SetCacheBatchFunc(fn func(...any) (map[K]V, error)) {
|
func (m *MapCache[K, V]) SetCacheBatchFn(fn func(...any) (map[K]V, error)) {
|
||||||
m.batchCacheFn = fn
|
m.batchCacheFn = fn
|
||||||
if m.cacheFunc == nil {
|
if m.cacheFunc == nil {
|
||||||
m.setCacheFn(fn)
|
m.setCacheFn(fn)
|
||||||
|
@ -68,102 +58,56 @@ func (m *MapCache[K, V]) setCacheFn(fn func(...any) (map[K]V, error)) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewMapCacheByFn[K comparable, V any](fn func(...any) (V, error), expireTime time.Duration) *MapCache[K, V] {
|
func NewMemoryMapCacheByFn[K comparable, V any](fn func(...any) (V, error), expireTime time.Duration) *MapCache[K, V] {
|
||||||
return &MapCache[K, V]{
|
return &MapCache[K, V]{
|
||||||
mutex: &sync.Mutex{},
|
data: NewMemoryMapCache[K, V](),
|
||||||
cacheFunc: fn,
|
cacheFunc: fn,
|
||||||
expireTime: expireTime,
|
expireTime: expireTime,
|
||||||
data: safety.NewMap[K, mapCacheStruct[V]](),
|
mux: sync.Mutex{},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
func NewMapCacheByBatchFn[K comparable, V any](fn func(...any) (map[K]V, error), expireTime time.Duration) *MapCache[K, V] {
|
func NewMemoryMapCacheByBatchFn[K comparable, V any](fn func(...any) (map[K]V, error), expireTime time.Duration) *MapCache[K, V] {
|
||||||
r := &MapCache[K, V]{
|
r := &MapCache[K, V]{
|
||||||
mutex: &sync.Mutex{},
|
data: NewMemoryMapCache[K, V](),
|
||||||
batchCacheFn: fn,
|
batchCacheFn: fn,
|
||||||
expireTime: expireTime,
|
expireTime: expireTime,
|
||||||
data: safety.NewMap[K, mapCacheStruct[V]](),
|
mux: sync.Mutex{},
|
||||||
}
|
}
|
||||||
r.setCacheFn(fn)
|
r.setCacheFn(fn)
|
||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *MapCache[K, V]) Flush() {
|
func (m *MapCache[K, V]) Flush(ctx context.Context) {
|
||||||
m.mutex.Lock()
|
m.mux.Lock()
|
||||||
defer m.mutex.Unlock()
|
defer m.mux.Unlock()
|
||||||
m.data = safety.NewMap[K, mapCacheStruct[V]]()
|
m.data.Flush(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *MapCache[K, V]) Get(k K) (V, bool) {
|
func (m *MapCache[K, V]) Get(ctx context.Context, k K) (V, bool) {
|
||||||
r, ok := m.data.Load(k)
|
return m.data.Get(ctx, k)
|
||||||
if ok {
|
|
||||||
return r.data, ok
|
|
||||||
}
|
|
||||||
var rr V
|
|
||||||
return rr, false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *MapCache[K, V]) Set(k K, v V) {
|
func (m *MapCache[K, V]) Set(ctx context.Context, k K, v V) {
|
||||||
m.set(k, v)
|
m.data.Set(ctx, k, v, m.expireTime)
|
||||||
}
|
|
||||||
|
|
||||||
func (m *MapCache[K, V]) SetByBatchFn(params ...any) error {
|
|
||||||
m.mutex.Lock()
|
|
||||||
defer m.mutex.Unlock()
|
|
||||||
|
|
||||||
r, err := m.batchCacheFn(params...)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
for k, v := range r {
|
|
||||||
m.set(k, v)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *MapCache[K, V]) set(k K, v V) {
|
|
||||||
data, ok := m.data.Load(k)
|
|
||||||
t := time.Now()
|
|
||||||
if !ok {
|
|
||||||
data.data = v
|
|
||||||
data.setTime = t
|
|
||||||
data.incr++
|
|
||||||
m.data.Store(k, data)
|
|
||||||
} else {
|
|
||||||
m.data.Store(k, mapCacheStruct[V]{
|
|
||||||
data: v,
|
|
||||||
setTime: t,
|
|
||||||
})
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *MapCache[K, V]) GetCache(c context.Context, key K, timeout time.Duration, params ...any) (V, error) {
|
func (m *MapCache[K, V]) GetCache(c context.Context, key K, timeout time.Duration, params ...any) (V, error) {
|
||||||
data, ok := m.data.Load(key)
|
data, ok := m.data.Get(c, key)
|
||||||
if !ok {
|
|
||||||
data = mapCacheStruct[V]{}
|
|
||||||
}
|
|
||||||
now := time.Duration(time.Now().UnixNano())
|
|
||||||
var err error
|
var err error
|
||||||
expired := time.Duration(data.setTime.UnixNano())+m.expireTime < now
|
if !ok || m.data.Ttl(c, key, m.expireTime) <= 0 {
|
||||||
//todo 这里应该判断下取出的值是否为零值,不过怎么操作呢?
|
ver := m.data.Ver(c, key)
|
||||||
if !ok || (ok && m.expireTime >= 0 && expired) {
|
|
||||||
t := data.incr
|
|
||||||
call := func() {
|
call := func() {
|
||||||
m.mutex.Lock()
|
m.mux.Lock()
|
||||||
defer m.mutex.Unlock()
|
defer m.mux.Unlock()
|
||||||
da, ok := m.data.Load(key)
|
if m.data.Ver(c, key) > ver {
|
||||||
if ok && da.incr > t {
|
data, _ = m.data.Get(c, key)
|
||||||
return
|
return
|
||||||
} else {
|
|
||||||
da = data
|
|
||||||
}
|
}
|
||||||
r, er := m.cacheFunc(params...)
|
data, err = m.cacheFunc(params...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err = er
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
m.set(key, r)
|
m.Set(c, key, data)
|
||||||
data.data = r
|
|
||||||
}
|
}
|
||||||
if timeout > 0 {
|
if timeout > 0 {
|
||||||
ctx, cancel := context.WithTimeout(c, timeout)
|
ctx, cancel := context.WithTimeout(c, timeout)
|
||||||
|
@ -183,48 +127,42 @@ func (m *MapCache[K, V]) GetCache(c context.Context, key K, timeout time.Duratio
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
return data.data, err
|
return data, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *MapCache[K, V]) GetCacheBatch(c context.Context, key []K, timeout time.Duration, params ...any) ([]V, error) {
|
func (m *MapCache[K, V]) GetCacheBatch(c context.Context, key []K, timeout time.Duration, params ...any) ([]V, error) {
|
||||||
var needFlush []K
|
|
||||||
var res []V
|
var res []V
|
||||||
t := 0
|
ver := 0
|
||||||
now := time.Duration(time.Now().UnixNano())
|
needFlush := slice.FilterAndMap(key, func(k K) (r K, ok bool) {
|
||||||
for _, k := range key {
|
if _, ok := m.data.Get(c, k); !ok {
|
||||||
d, ok := m.data.Load(k)
|
return k, true
|
||||||
if !ok {
|
|
||||||
needFlush = append(needFlush, k)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
expired := time.Duration(d.setTime.UnixNano())+m.expireTime < now
|
|
||||||
if expired {
|
|
||||||
needFlush = append(needFlush, k)
|
|
||||||
}
|
|
||||||
t = t + d.incr
|
|
||||||
}
|
}
|
||||||
|
ver += m.data.Ver(c, k)
|
||||||
|
return
|
||||||
|
})
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
//todo 这里应该判断下取出的值是否为零值,不过怎么操作呢?
|
|
||||||
if len(needFlush) > 0 {
|
if len(needFlush) > 0 {
|
||||||
call := func() {
|
call := func() {
|
||||||
m.mutex.Lock()
|
m.mux.Lock()
|
||||||
defer m.mutex.Unlock()
|
defer m.mux.Unlock()
|
||||||
tt := 0
|
|
||||||
for _, dd := range needFlush {
|
vers := slice.Reduce(needFlush, func(t K, r int) int {
|
||||||
if ddd, ok := m.data.Load(dd); ok {
|
r += m.data.Ver(c, t)
|
||||||
tt = tt + ddd.incr
|
return r
|
||||||
}
|
}, 0)
|
||||||
}
|
|
||||||
if tt > t {
|
if vers > ver {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
r, er := m.batchCacheFn(params...)
|
r, er := m.batchCacheFn(params...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err = er
|
err = er
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
for k, v := range r {
|
for k, v := range r {
|
||||||
m.set(k, v)
|
m.Set(c, k, v)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if timeout > 0 {
|
if timeout > 0 {
|
||||||
|
@ -244,23 +182,14 @@ func (m *MapCache[K, V]) GetCacheBatch(c context.Context, key []K, timeout time.
|
||||||
call()
|
call()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for _, k := range key {
|
res = slice.FilterAndMap(key, func(k K) (V, bool) {
|
||||||
d, ok := m.data.Load(k)
|
return m.data.Get(c, k)
|
||||||
if ok {
|
})
|
||||||
res = append(res, d.data)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *MapCache[K, V]) ClearExpired() {
|
func (m *MapCache[K, V]) ClearExpired(ctx context.Context) {
|
||||||
now := time.Duration(time.Now().UnixNano())
|
m.mux.Lock()
|
||||||
m.mutex.Lock()
|
defer m.mux.Unlock()
|
||||||
defer m.mutex.Unlock()
|
m.data.ClearExpired(ctx, m.expireTime)
|
||||||
m.data.Range(func(k K, v mapCacheStruct[V]) bool {
|
|
||||||
if now > time.Duration(v.setTime.UnixNano())+m.expireTime {
|
|
||||||
m.data.Delete(k)
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
82
cache/memorymapcache.go
vendored
Normal file
82
cache/memorymapcache.go
vendored
Normal file
|
@ -0,0 +1,82 @@
|
||||||
|
package cache
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"github.com/fthvgb1/wp-go/helper/number"
|
||||||
|
"github.com/fthvgb1/wp-go/safety"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type MemoryMapCache[K comparable, V any] struct {
|
||||||
|
safety.Map[K, mapVal[V]]
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewMemoryMapCache[K comparable, V any]() *MemoryMapCache[K, V] {
|
||||||
|
return &MemoryMapCache[K, V]{Map: safety.NewMap[K, mapVal[V]]()}
|
||||||
|
}
|
||||||
|
|
||||||
|
type mapVal[T any] struct {
|
||||||
|
setTime time.Time
|
||||||
|
ver int
|
||||||
|
data T
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *MemoryMapCache[K, V]) Get(_ context.Context, key K) (r V, ok bool) {
|
||||||
|
v, ok := m.Load(key)
|
||||||
|
if ok {
|
||||||
|
return v.data, true
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *MemoryMapCache[K, V]) Set(_ context.Context, key K, val V, _ time.Duration) {
|
||||||
|
v, ok := m.Load(key)
|
||||||
|
t := time.Now()
|
||||||
|
if ok {
|
||||||
|
v.data = val
|
||||||
|
v.setTime = t
|
||||||
|
v.ver++
|
||||||
|
} else {
|
||||||
|
v = mapVal[V]{
|
||||||
|
setTime: t,
|
||||||
|
ver: 1,
|
||||||
|
data: val,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m.Store(key, v)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *MemoryMapCache[K, V]) Ttl(_ context.Context, key K, expire time.Duration) time.Duration {
|
||||||
|
v, ok := m.Load(key)
|
||||||
|
if !ok {
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
return number.Max(time.Duration(0), expire-time.Duration(time.Now().UnixNano()-v.setTime.UnixNano()))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *MemoryMapCache[K, V]) Ver(_ context.Context, key K) int {
|
||||||
|
v, ok := m.Load(key)
|
||||||
|
if !ok {
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
return v.ver
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *MemoryMapCache[K, V]) Flush(context.Context) {
|
||||||
|
m.Map = safety.NewMap[K, mapVal[V]]()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *MemoryMapCache[K, V]) Delete(_ context.Context, key K) {
|
||||||
|
m.Map.Delete(key)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *MemoryMapCache[K, V]) ClearExpired(_ context.Context, expire time.Duration) {
|
||||||
|
now := time.Duration(time.Now().UnixNano())
|
||||||
|
|
||||||
|
m.Range(func(k K, v mapVal[V]) bool {
|
||||||
|
if now > time.Duration(v.setTime.UnixNano())+expire {
|
||||||
|
m.Map.Delete(k)
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
}
|
|
@ -111,7 +111,7 @@ func PostComment(c *gin.Context) {
|
||||||
err = er
|
err = er
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
cache.NewCommentCache().Set(up.RawQuery, string(s))
|
cache.NewCommentCache().Set(c, up.RawQuery, string(s))
|
||||||
c.Redirect(http.StatusFound, res.Header.Get("Location"))
|
c.Redirect(http.StatusFound, res.Header.Get("Location"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -76,7 +76,7 @@ func Detail(c *gin.Context) {
|
||||||
if post.PostPassword != "" && pw != post.PostPassword {
|
if post.PostPassword != "" && pw != post.PostPassword {
|
||||||
plugins.PasswdProjectContent(&post)
|
plugins.PasswdProjectContent(&post)
|
||||||
showComment = false
|
showComment = false
|
||||||
} else if s, ok := cache.NewCommentCache().Get(c.Request.URL.RawQuery); ok && s != "" && (post.PostPassword == "" || post.PostPassword != "" && pw == post.PostPassword) {
|
} else if s, ok := cache.NewCommentCache().Get(c, c.Request.URL.RawQuery); ok && s != "" && (post.PostPassword == "" || post.PostPassword != "" && pw == post.PostPassword) {
|
||||||
c.Writer.WriteHeader(http.StatusOK)
|
c.Writer.WriteHeader(http.StatusOK)
|
||||||
c.Writer.Header().Set("Content-Type", "text/html; charset=utf-8")
|
c.Writer.Header().Set("Content-Type", "text/html; charset=utf-8")
|
||||||
_, err = c.Writer.WriteString(s)
|
_, err = c.Writer.WriteString(s)
|
||||||
|
|
|
@ -50,7 +50,7 @@ func setFeed(s string, c *gin.Context, t time.Time) {
|
||||||
|
|
||||||
func PostFeed(c *gin.Context) {
|
func PostFeed(c *gin.Context) {
|
||||||
id := c.Param("id")
|
id := c.Param("id")
|
||||||
if !isCacheExpired(c, cache.PostFeedCache().GetLastSetTime(id)) {
|
if !isCacheExpired(c, cache.PostFeedCache().GetLastSetTime(c, id)) {
|
||||||
c.Status(http.StatusNotModified)
|
c.Status(http.StatusNotModified)
|
||||||
} else {
|
} else {
|
||||||
s, err := cache.PostFeedCache().GetCache(c, id, time.Second, c, id)
|
s, err := cache.PostFeedCache().GetCache(c, id, time.Second, c, id)
|
||||||
|
@ -60,7 +60,7 @@ func PostFeed(c *gin.Context) {
|
||||||
c.Error(err)
|
c.Error(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
setFeed(s, c, cache.PostFeedCache().GetLastSetTime(id))
|
setFeed(s, c, cache.PostFeedCache().GetLastSetTime(c, id))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
79
internal/pkg/cache/cache.go
vendored
79
internal/pkg/cache/cache.go
vendored
|
@ -43,6 +43,8 @@ var allUsernameCache *cache.VarCache[map[string]struct{}]
|
||||||
|
|
||||||
var headerImagesCache *cache.MapCache[string, []models.PostThumbnail]
|
var headerImagesCache *cache.MapCache[string, []models.PostThumbnail]
|
||||||
|
|
||||||
|
var ctx context.Context
|
||||||
|
|
||||||
func InitActionsCommonCache() {
|
func InitActionsCommonCache() {
|
||||||
c := config.Conf.Load()
|
c := config.Conf.Load()
|
||||||
archivesCaches = &Arch{
|
archivesCaches = &Arch{
|
||||||
|
@ -50,17 +52,17 @@ func InitActionsCommonCache() {
|
||||||
setCacheFunc: dao.Archives,
|
setCacheFunc: dao.Archives,
|
||||||
}
|
}
|
||||||
|
|
||||||
searchPostIdsCache = cache.NewMapCacheByFn[string](dao.SearchPostIds, c.SearchPostCacheTime)
|
searchPostIdsCache = cache.NewMemoryMapCacheByFn[string](dao.SearchPostIds, c.SearchPostCacheTime)
|
||||||
|
|
||||||
postListIdsCache = cache.NewMapCacheByFn[string](dao.SearchPostIds, c.PostListCacheTime)
|
postListIdsCache = cache.NewMemoryMapCacheByFn[string](dao.SearchPostIds, c.PostListCacheTime)
|
||||||
|
|
||||||
monthPostsCache = cache.NewMapCacheByFn[string](dao.MonthPost, c.MonthPostCacheTime)
|
monthPostsCache = cache.NewMemoryMapCacheByFn[string](dao.MonthPost, c.MonthPostCacheTime)
|
||||||
|
|
||||||
postContextCache = cache.NewMapCacheByFn[uint64](dao.GetPostContext, c.ContextPostCacheTime)
|
postContextCache = cache.NewMemoryMapCacheByFn[uint64](dao.GetPostContext, c.ContextPostCacheTime)
|
||||||
|
|
||||||
postsCache = cache.NewMapCacheByBatchFn(dao.GetPostsByIds, c.PostDataCacheTime)
|
postsCache = cache.NewMemoryMapCacheByBatchFn(dao.GetPostsByIds, c.PostDataCacheTime)
|
||||||
|
|
||||||
postMetaCache = cache.NewMapCacheByBatchFn(dao.GetPostMetaByPostIds, c.PostDataCacheTime)
|
postMetaCache = cache.NewMemoryMapCacheByBatchFn(dao.GetPostMetaByPostIds, c.PostDataCacheTime)
|
||||||
|
|
||||||
categoryAndTagsCaches = cache.NewVarCache(dao.CategoriesAndTags, c.CategoryCacheTime)
|
categoryAndTagsCaches = cache.NewVarCache(dao.CategoriesAndTags, c.CategoryCacheTime)
|
||||||
|
|
||||||
|
@ -68,58 +70,61 @@ func InitActionsCommonCache() {
|
||||||
|
|
||||||
recentCommentsCaches = cache.NewVarCache(dao.RecentComments, c.RecentCommentsCacheTime)
|
recentCommentsCaches = cache.NewVarCache(dao.RecentComments, c.RecentCommentsCacheTime)
|
||||||
|
|
||||||
postCommentCaches = cache.NewMapCacheByFn[uint64](dao.PostComments, c.PostCommentsCacheTime)
|
postCommentCaches = cache.NewMemoryMapCacheByFn[uint64](dao.PostComments, c.PostCommentsCacheTime)
|
||||||
|
|
||||||
maxPostIdCache = cache.NewVarCache(dao.GetMaxPostId, c.MaxPostIdCacheTime)
|
maxPostIdCache = cache.NewVarCache(dao.GetMaxPostId, c.MaxPostIdCacheTime)
|
||||||
|
|
||||||
usersCache = cache.NewMapCacheByFn[uint64](dao.GetUserById, c.UserInfoCacheTime)
|
usersCache = cache.NewMemoryMapCacheByFn[uint64](dao.GetUserById, c.UserInfoCacheTime)
|
||||||
|
|
||||||
usersNameCache = cache.NewMapCacheByFn[string](dao.GetUserByName, c.UserInfoCacheTime)
|
usersNameCache = cache.NewMemoryMapCacheByFn[string](dao.GetUserByName, c.UserInfoCacheTime)
|
||||||
|
|
||||||
commentsCache = cache.NewMapCacheByBatchFn(dao.GetCommentByIds, c.CommentsCacheTime)
|
commentsCache = cache.NewMemoryMapCacheByBatchFn(dao.GetCommentByIds, c.CommentsCacheTime)
|
||||||
|
|
||||||
feedCache = cache.NewVarCache(feed, time.Hour)
|
feedCache = cache.NewVarCache(feed, time.Hour)
|
||||||
|
|
||||||
postFeedCache = cache.NewMapCacheByFn[string](postFeed, time.Hour)
|
postFeedCache = cache.NewMemoryMapCacheByFn[string](postFeed, time.Hour)
|
||||||
|
|
||||||
commentsFeedCache = cache.NewVarCache(commentsFeed, time.Hour)
|
commentsFeedCache = cache.NewVarCache(commentsFeed, time.Hour)
|
||||||
|
|
||||||
newCommentCache = cache.NewMapCacheByFn[string, string](nil, 15*time.Minute)
|
newCommentCache = cache.NewMemoryMapCacheByFn[string, string](nil, 15*time.Minute)
|
||||||
|
|
||||||
allUsernameCache = cache.NewVarCache(dao.AllUsername, c.UserInfoCacheTime)
|
allUsernameCache = cache.NewVarCache(dao.AllUsername, c.UserInfoCacheTime)
|
||||||
|
|
||||||
headerImagesCache = cache.NewMapCacheByFn[string](getHeaderImages, c.ThemeHeaderImagCacheTime)
|
headerImagesCache = cache.NewMemoryMapCacheByFn[string](getHeaderImages, c.ThemeHeaderImagCacheTime)
|
||||||
|
|
||||||
|
ctx = context.Background()
|
||||||
|
|
||||||
InitFeed()
|
InitFeed()
|
||||||
}
|
}
|
||||||
|
|
||||||
func ClearCache() {
|
func ClearCache() {
|
||||||
searchPostIdsCache.ClearExpired()
|
searchPostIdsCache.ClearExpired(ctx)
|
||||||
postsCache.ClearExpired()
|
searchPostIdsCache.ClearExpired(ctx)
|
||||||
postMetaCache.ClearExpired()
|
postsCache.ClearExpired(ctx)
|
||||||
postListIdsCache.ClearExpired()
|
postMetaCache.ClearExpired(ctx)
|
||||||
monthPostsCache.ClearExpired()
|
postListIdsCache.ClearExpired(ctx)
|
||||||
postContextCache.ClearExpired()
|
monthPostsCache.ClearExpired(ctx)
|
||||||
usersCache.ClearExpired()
|
postContextCache.ClearExpired(ctx)
|
||||||
commentsCache.ClearExpired()
|
usersCache.ClearExpired(ctx)
|
||||||
usersNameCache.ClearExpired()
|
commentsCache.ClearExpired(ctx)
|
||||||
postFeedCache.ClearExpired()
|
usersNameCache.ClearExpired(ctx)
|
||||||
newCommentCache.ClearExpired()
|
postFeedCache.ClearExpired(ctx)
|
||||||
headerImagesCache.ClearExpired()
|
newCommentCache.ClearExpired(ctx)
|
||||||
|
headerImagesCache.ClearExpired(ctx)
|
||||||
}
|
}
|
||||||
func FlushCache() {
|
func FlushCache() {
|
||||||
searchPostIdsCache.Flush()
|
searchPostIdsCache.Flush(ctx)
|
||||||
postsCache.Flush()
|
postsCache.Flush(ctx)
|
||||||
postMetaCache.Flush()
|
postMetaCache.Flush(ctx)
|
||||||
postListIdsCache.Flush()
|
postListIdsCache.Flush(ctx)
|
||||||
monthPostsCache.Flush()
|
monthPostsCache.Flush(ctx)
|
||||||
postContextCache.Flush()
|
postContextCache.Flush(ctx)
|
||||||
usersCache.Flush()
|
usersCache.Flush(ctx)
|
||||||
commentsCache.Flush()
|
commentsCache.Flush(ctx)
|
||||||
usersCache.Flush()
|
usersCache.Flush(ctx)
|
||||||
postFeedCache.Flush()
|
postFeedCache.Flush(ctx)
|
||||||
newCommentCache.Flush()
|
newCommentCache.Flush(ctx)
|
||||||
headerImagesCache.Flush()
|
headerImagesCache.Flush(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
func Archives(ctx context.Context) (r []models.PostArchive) {
|
func Archives(ctx context.Context) (r []models.PostArchive) {
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package plugins
|
package plugins
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/fthvgb1/wp-go/cache"
|
"github.com/fthvgb1/wp-go/cache"
|
||||||
"github.com/fthvgb1/wp-go/internal/pkg/config"
|
"github.com/fthvgb1/wp-go/internal/pkg/config"
|
||||||
|
@ -12,16 +13,18 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
var digestCache *cache.MapCache[uint64, string]
|
var digestCache *cache.MapCache[uint64, string]
|
||||||
|
var ctx context.Context
|
||||||
|
|
||||||
func InitDigestCache() {
|
func InitDigestCache() {
|
||||||
digestCache = cache.NewMapCacheByFn[uint64](digestRaw, config.Conf.Load().DigestCacheTime)
|
ctx = context.Background()
|
||||||
|
digestCache = cache.NewMemoryMapCacheByFn[uint64](digestRaw, config.Conf.Load().DigestCacheTime)
|
||||||
}
|
}
|
||||||
|
|
||||||
func ClearDigestCache() {
|
func ClearDigestCache() {
|
||||||
digestCache.ClearExpired()
|
digestCache.ClearExpired(ctx)
|
||||||
}
|
}
|
||||||
func FlushCache() {
|
func FlushCache() {
|
||||||
digestCache.Flush()
|
digestCache.Flush(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
func digestRaw(arg ...any) (string, error) {
|
func digestRaw(arg ...any) (string, error) {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user