Files
go-gin-api/internal/api/repository/redis/redis.go
新亮 8ed27cdce1 feature(1.2.8): 使用 embed 打包静态资源
- go version 升级为 1.16
- 使用 embed 特性,将静态资源打包进二进制文件
- 优化代码
2021-11-20 15:01:50 +08:00

230 lines
4.8 KiB
Go

package redis
import (
"strings"
"time"
"github.com/xinliangnote/go-gin-api/configs"
"github.com/xinliangnote/go-gin-api/pkg/errors"
"github.com/xinliangnote/go-gin-api/pkg/timeutil"
"github.com/xinliangnote/go-gin-api/pkg/trace"
"github.com/go-redis/redis/v7"
)
type Option func(*option)
type Trace = trace.T
type option struct {
Trace *trace.Trace
Redis *trace.Redis
}
func newOption() *option {
return &option{}
}
var _ Repo = (*cacheRepo)(nil)
type Repo interface {
i()
Set(key, value string, ttl time.Duration, options ...Option) error
Get(key string, options ...Option) (string, error)
TTL(key string) (time.Duration, error)
Expire(key string, ttl time.Duration) bool
ExpireAt(key string, ttl time.Time) bool
Del(key string, options ...Option) bool
Exists(keys ...string) bool
Incr(key string, options ...Option) int64
Close() error
Version() string
}
type cacheRepo struct {
client *redis.Client
}
func New() (Repo, error) {
client, err := redisConnect()
if err != nil {
return nil, err
}
return &cacheRepo{
client: client,
}, nil
}
func (c *cacheRepo) i() {}
func redisConnect() (*redis.Client, error) {
cfg := configs.Get().Redis
client := redis.NewClient(&redis.Options{
Addr: cfg.Addr,
Password: cfg.Pass,
DB: cfg.Db,
MaxRetries: cfg.MaxRetries,
PoolSize: cfg.PoolSize,
MinIdleConns: cfg.MinIdleConns,
})
if err := client.Ping().Err(); err != nil {
return nil, errors.Wrap(err, "ping redis err")
}
return client, nil
}
// Set set some <key,value> into redis
func (c *cacheRepo) Set(key, value string, ttl time.Duration, options ...Option) error {
ts := time.Now()
opt := newOption()
defer func() {
if opt.Trace != nil {
opt.Redis.Timestamp = timeutil.CSTLayoutString()
opt.Redis.Handle = "set"
opt.Redis.Key = key
opt.Redis.Value = value
opt.Redis.TTL = ttl.Minutes()
opt.Redis.CostSeconds = time.Since(ts).Seconds()
opt.Trace.AppendRedis(opt.Redis)
}
}()
for _, f := range options {
f(opt)
}
if err := c.client.Set(key, value, ttl).Err(); err != nil {
return errors.Wrapf(err, "redis set key: %s err", key)
}
return nil
}
// Get get some key from redis
func (c *cacheRepo) Get(key string, options ...Option) (string, error) {
ts := time.Now()
opt := newOption()
defer func() {
if opt.Trace != nil {
opt.Redis.Timestamp = timeutil.CSTLayoutString()
opt.Redis.Handle = "get"
opt.Redis.Key = key
opt.Redis.CostSeconds = time.Since(ts).Seconds()
opt.Trace.AppendRedis(opt.Redis)
}
}()
for _, f := range options {
f(opt)
}
value, err := c.client.Get(key).Result()
if err != nil {
return "", errors.Wrapf(err, "redis get key: %s err", key)
}
return value, nil
}
// TTL get some key from redis
func (c *cacheRepo) TTL(key string) (time.Duration, error) {
ttl, err := c.client.TTL(key).Result()
if err != nil {
return -1, errors.Wrapf(err, "redis get key: %s err", key)
}
return ttl, nil
}
// Expire expire some key
func (c *cacheRepo) Expire(key string, ttl time.Duration) bool {
ok, _ := c.client.Expire(key, ttl).Result()
return ok
}
// ExpireAt expire some key at some time
func (c *cacheRepo) ExpireAt(key string, ttl time.Time) bool {
ok, _ := c.client.ExpireAt(key, ttl).Result()
return ok
}
func (c *cacheRepo) Exists(keys ...string) bool {
if len(keys) == 0 {
return true
}
value, _ := c.client.Exists(keys...).Result()
return value > 0
}
func (c *cacheRepo) Del(key string, options ...Option) bool {
ts := time.Now()
opt := newOption()
defer func() {
if opt.Trace != nil {
opt.Redis.Timestamp = timeutil.CSTLayoutString()
opt.Redis.Handle = "del"
opt.Redis.Key = key
opt.Redis.CostSeconds = time.Since(ts).Seconds()
opt.Trace.AppendRedis(opt.Redis)
}
}()
for _, f := range options {
f(opt)
}
if key == "" {
return true
}
value, _ := c.client.Del(key).Result()
return value > 0
}
func (c *cacheRepo) Incr(key string, options ...Option) int64 {
ts := time.Now()
opt := newOption()
defer func() {
if opt.Trace != nil {
opt.Redis.Timestamp = timeutil.CSTLayoutString()
opt.Redis.Handle = "incr"
opt.Redis.Key = key
opt.Redis.CostSeconds = time.Since(ts).Seconds()
opt.Trace.AppendRedis(opt.Redis)
}
}()
for _, f := range options {
f(opt)
}
value, _ := c.client.Incr(key).Result()
return value
}
// Close close redis client
func (c *cacheRepo) Close() error {
return c.client.Close()
}
// WithTrace 设置trace信息
func WithTrace(t Trace) Option {
return func(opt *option) {
if t != nil {
opt.Trace = t.(*trace.Trace)
opt.Redis = new(trace.Redis)
}
}
}
// Version redis server version
func (c *cacheRepo) Version() string {
server := c.client.Info("server").Val()
spl1 := strings.Split(server, "# Server")
spl2 := strings.Split(spl1[1], "redis_version:")
spl3 := strings.Split(spl2[1], "redis_git_sha1:")
return spl3[0]
}