BREAKING CHANGE: The original Go module name was `github.com/ArtalkJS/Artalk`, which has now been modified to `github.com/artalkjs/artalk/v2` (all lowercase). This change may affect the CI pipeline or other areas if you are compiling the Artalk server and have specified the fixed Go module name. Regarding the original `-ldflags -X github.com/ArtalkJS/Artalk/internal/config.Version` and `CommitHash` definitions, please remove them, as they are now obsolete. The `Version` has been hardcoded into the Go code, and the `CommitHash` is now read from the Go build info via runtime/debug’s vcs.revision value. This change only affects the server developers and does not impact the frontend UI client.
99 lines
2.4 KiB
Go
99 lines
2.4 KiB
Go
package cache
|
|
|
|
import (
|
|
"context"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/allegro/bigcache/v3"
|
|
"github.com/artalkjs/artalk/v2/internal/config"
|
|
"github.com/artalkjs/artalk/v2/internal/log"
|
|
"github.com/bradfitz/gomemcache/memcache"
|
|
lib_cache "github.com/eko/gocache/lib/v4/cache"
|
|
"github.com/eko/gocache/lib/v4/marshaler"
|
|
"github.com/eko/gocache/lib/v4/store"
|
|
bigcache_store "github.com/eko/gocache/store/bigcache/v4"
|
|
memcache_store "github.com/eko/gocache/store/memcache/v4"
|
|
redis_store "github.com/eko/gocache/store/redis/v4"
|
|
"github.com/redis/go-redis/v9"
|
|
)
|
|
|
|
type Cache struct {
|
|
ttl time.Duration
|
|
ctx context.Context
|
|
cancel context.CancelFunc
|
|
instance *lib_cache.Cache[any]
|
|
marshal *marshaler.Marshaler
|
|
}
|
|
|
|
func (cache *Cache) Close() {
|
|
cache.cancel()
|
|
cache.marshal = nil
|
|
cache.instance = nil
|
|
}
|
|
|
|
func New(conf config.CacheConf) (*Cache, error) {
|
|
// create new context
|
|
ctx, cancel := context.WithCancel(context.Background())
|
|
|
|
cache := &Cache{
|
|
ttl: time.Duration(conf.GetExpiresTime()),
|
|
ctx: ctx,
|
|
cancel: cancel,
|
|
}
|
|
|
|
var cacheStore store.StoreInterface
|
|
|
|
switch conf.Type {
|
|
|
|
case config.CacheTypeBuiltin:
|
|
// 内建缓存
|
|
bigcacheClient, err := bigcache.New(context.Background(), bigcache.DefaultConfig(
|
|
// Tip: 内建缓存过期时间是一样的,只有 Redis/Memcache 才能设置单个 item 的
|
|
cache.ttl,
|
|
))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
cacheStore = bigcache_store.NewBigcache(bigcacheClient) // No options provided (as second argument)
|
|
|
|
case config.CacheTypeRedis:
|
|
// Redis
|
|
network := "tcp"
|
|
if conf.Redis.Network != "" {
|
|
network = conf.Redis.Network
|
|
}
|
|
|
|
cacheStore = redis_store.NewRedis(redis.NewClient(&redis.Options{
|
|
Network: network,
|
|
Addr: conf.Server,
|
|
Username: conf.Redis.Username,
|
|
Password: conf.Redis.Password,
|
|
DB: conf.Redis.DB,
|
|
}))
|
|
|
|
case config.CacheTypeMemcache:
|
|
// Memcache
|
|
servers := strings.Split(conf.Server, ",")
|
|
cacheStore = memcache_store.NewMemcache(
|
|
memcache.New(servers...),
|
|
store.WithExpiration(cache.ttl),
|
|
)
|
|
|
|
default:
|
|
log.Fatal(`Invalid cache type "` + conf.Type + `", please check config option "cache.type"`)
|
|
|
|
}
|
|
|
|
cache.instance = lib_cache.New[any](cacheStore)
|
|
|
|
// marshaler wrapper
|
|
// marshaler using VmihailencoMsgpack
|
|
// @link https://github.com/vmihailenco/msgpack
|
|
// Benchmarks
|
|
// @link https://github.com/alecthomas/go_serialization_benchmarks
|
|
cache.marshal = marshaler.New(cache.instance)
|
|
|
|
return cache, nil
|
|
}
|