Files
go-gin-api/internal/api/repository/redis/redis.go

230 lines
4.8 KiB
Go
Raw Normal View History

package redis
2021-01-09 20:10:13 +08:00
import (
"strings"
2021-01-09 20:10:13 +08:00
"time"
"github.com/xinliangnote/go-gin-api/configs"
2021-05-15 13:01:30 +08:00
"github.com/xinliangnote/go-gin-api/pkg/errors"
"github.com/xinliangnote/go-gin-api/pkg/timeutil"
2021-02-02 20:42:51 +08:00
"github.com/xinliangnote/go-gin-api/pkg/trace"
2021-01-09 20:10:13 +08:00
"github.com/go-redis/redis/v7"
)
2021-01-23 16:46:01 +08:00
type Option func(*option)
type Trace = trace.T
type option struct {
Trace *trace.Trace
Redis *trace.Redis
}
func newOption() *option {
return &option{}
}
2021-01-09 20:10:13 +08:00
var _ Repo = (*cacheRepo)(nil)
type Repo interface {
i()
2021-01-23 16:46:01 +08:00
Set(key, value string, ttl time.Duration, options ...Option) error
Get(key string, options ...Option) (string, error)
2021-01-09 20:10:13 +08:00
TTL(key string) (time.Duration, error)
Expire(key string, ttl time.Duration) bool
ExpireAt(key string, ttl time.Time) bool
2021-04-10 15:05:50 +08:00
Del(key string, options ...Option) bool
2021-03-06 13:28:38 +08:00
Exists(keys ...string) bool
2021-01-23 16:46:01 +08:00
Incr(key string, options ...Option) int64
2021-02-09 09:52:50 +08:00
Close() error
Version() string
2021-01-09 20:10:13 +08:00
}
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
2021-01-23 16:46:01 +08:00
func (c *cacheRepo) Set(key, value string, ttl time.Duration, options ...Option) error {
2021-01-31 14:51:41 +08:00
ts := time.Now()
2021-01-23 16:46:01 +08:00
opt := newOption()
defer func() {
if opt.Trace != nil {
opt.Redis.Timestamp = timeutil.CSTLayoutString()
2021-01-23 16:46:01 +08:00
opt.Redis.Handle = "set"
opt.Redis.Key = key
opt.Redis.Value = value
2021-01-31 14:51:41 +08:00
opt.Redis.TTL = ttl.Minutes()
opt.Redis.CostSeconds = time.Since(ts).Seconds()
2021-01-23 16:46:01 +08:00
opt.Trace.AppendRedis(opt.Redis)
}
}()
for _, f := range options {
f(opt)
}
2021-01-09 20:10:13 +08:00
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
2021-01-23 16:46:01 +08:00
func (c *cacheRepo) Get(key string, options ...Option) (string, error) {
2021-01-31 14:51:41 +08:00
ts := time.Now()
2021-01-23 16:46:01 +08:00
opt := newOption()
defer func() {
if opt.Trace != nil {
opt.Redis.Timestamp = timeutil.CSTLayoutString()
2021-01-23 16:46:01 +08:00
opt.Redis.Handle = "get"
opt.Redis.Key = key
2021-01-31 14:51:41 +08:00
opt.Redis.CostSeconds = time.Since(ts).Seconds()
2021-01-23 16:46:01 +08:00
opt.Trace.AppendRedis(opt.Redis)
}
}()
for _, f := range options {
f(opt)
}
2021-01-09 20:10:13 +08:00
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
}
2021-03-06 13:28:38 +08:00
func (c *cacheRepo) Exists(keys ...string) bool {
if len(keys) == 0 {
return true
}
value, _ := c.client.Exists(keys...).Result()
return value > 0
}
2021-04-10 15:05:50 +08:00
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()
2021-04-10 15:05:50 +08:00
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 == "" {
2021-01-09 20:10:13 +08:00
return true
}
2021-04-10 15:05:50 +08:00
value, _ := c.client.Del(key).Result()
2021-01-09 20:10:13 +08:00
return value > 0
}
2021-01-23 16:46:01 +08:00
func (c *cacheRepo) Incr(key string, options ...Option) int64 {
2021-01-31 14:51:41 +08:00
ts := time.Now()
2021-01-23 16:46:01 +08:00
opt := newOption()
defer func() {
if opt.Trace != nil {
opt.Redis.Timestamp = timeutil.CSTLayoutString()
2021-01-23 16:46:01 +08:00
opt.Redis.Handle = "incr"
opt.Redis.Key = key
2021-01-31 14:51:41 +08:00
opt.Redis.CostSeconds = time.Since(ts).Seconds()
2021-01-23 16:46:01 +08:00
opt.Trace.AppendRedis(opt.Redis)
}
}()
for _, f := range options {
f(opt)
}
2021-01-09 20:10:13 +08:00
value, _ := c.client.Incr(key).Result()
return value
}
// Close close redis client
2021-02-09 09:52:50 +08:00
func (c *cacheRepo) Close() error {
return c.client.Close()
2021-01-09 20:10:13 +08:00
}
2021-01-23 16:46:01 +08:00
// 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]
}