2021-05-24 07:27:41 +08:00
|
|
|
|
package cache
|
2018-04-04 18:44:00 +00:00
|
|
|
|
|
|
|
|
|
|
import (
|
2022-03-13 01:12:29 +08:00
|
|
|
|
. "code.hoteas.com/golang/hotime/common"
|
2018-04-04 18:44:00 +00:00
|
|
|
|
"github.com/garyburd/redigo/redis"
|
|
|
|
|
|
"strings"
|
2026-01-22 04:36:52 +08:00
|
|
|
|
"sync"
|
2020-02-20 14:20:56 +08:00
|
|
|
|
"time"
|
2018-04-04 18:44:00 +00:00
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
type CacheRedis struct {
|
2021-05-28 22:52:22 +08:00
|
|
|
|
TimeOut int64
|
|
|
|
|
|
DbSet bool
|
|
|
|
|
|
SessionSet bool
|
|
|
|
|
|
Host string
|
|
|
|
|
|
Pwd string
|
|
|
|
|
|
Port int64
|
2026-01-22 04:36:52 +08:00
|
|
|
|
pool *redis.Pool
|
2021-05-28 22:52:22 +08:00
|
|
|
|
tag int64
|
2021-05-25 20:27:24 +08:00
|
|
|
|
ContextBase
|
2021-05-28 22:52:22 +08:00
|
|
|
|
*Error
|
2026-01-22 04:36:52 +08:00
|
|
|
|
initOnce sync.Once
|
2021-05-28 22:52:22 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2022-03-13 01:48:54 +08:00
|
|
|
|
func (that *CacheRedis) GetError() *Error {
|
2021-05-28 22:52:22 +08:00
|
|
|
|
|
2022-03-13 01:48:54 +08:00
|
|
|
|
return that.Error
|
2021-05-28 22:52:22 +08:00
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2022-03-13 01:48:54 +08:00
|
|
|
|
func (that *CacheRedis) SetError(err *Error) {
|
|
|
|
|
|
that.Error = err
|
2018-04-04 18:44:00 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-01-22 02:44:53 +08:00
|
|
|
|
// 唯一标志
|
2022-03-13 01:48:54 +08:00
|
|
|
|
func (that *CacheRedis) GetTag() int64 {
|
2018-04-04 18:44:00 +00:00
|
|
|
|
|
2022-03-13 01:48:54 +08:00
|
|
|
|
if that.tag == int64(0) {
|
|
|
|
|
|
that.tag = time.Now().UnixNano()
|
2018-04-04 18:44:00 +00:00
|
|
|
|
}
|
2022-03-13 01:48:54 +08:00
|
|
|
|
return that.tag
|
2018-04-04 18:44:00 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-01-22 04:36:52 +08:00
|
|
|
|
// initPool 初始化连接池(只执行一次)
|
|
|
|
|
|
func (that *CacheRedis) initPool() {
|
|
|
|
|
|
that.initOnce.Do(func() {
|
|
|
|
|
|
that.pool = &redis.Pool{
|
|
|
|
|
|
MaxIdle: 10, // 最大空闲连接数
|
|
|
|
|
|
MaxActive: 100, // 最大活跃连接数,0表示无限制
|
|
|
|
|
|
IdleTimeout: 5 * time.Minute, // 空闲连接超时时间
|
|
|
|
|
|
Wait: true, // 当连接池耗尽时是否等待
|
|
|
|
|
|
Dial: func() (redis.Conn, error) {
|
|
|
|
|
|
conn, err := redis.Dial("tcp", that.Host+":"+ObjToStr(that.Port),
|
|
|
|
|
|
redis.DialConnectTimeout(5*time.Second),
|
|
|
|
|
|
redis.DialReadTimeout(3*time.Second),
|
|
|
|
|
|
redis.DialWriteTimeout(3*time.Second),
|
|
|
|
|
|
)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
if that.Pwd != "" {
|
|
|
|
|
|
if _, err := conn.Do("AUTH", that.Pwd); err != nil {
|
|
|
|
|
|
conn.Close()
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
return conn, nil
|
|
|
|
|
|
},
|
|
|
|
|
|
TestOnBorrow: func(c redis.Conn, t time.Time) error {
|
|
|
|
|
|
if time.Since(t) < time.Minute {
|
|
|
|
|
|
return nil
|
|
|
|
|
|
}
|
|
|
|
|
|
_, err := c.Do("PING")
|
|
|
|
|
|
return err
|
|
|
|
|
|
},
|
2021-05-28 23:48:33 +08:00
|
|
|
|
}
|
2026-01-22 04:36:52 +08:00
|
|
|
|
})
|
|
|
|
|
|
}
|
2021-05-28 23:48:33 +08:00
|
|
|
|
|
2026-01-22 04:36:52 +08:00
|
|
|
|
// getConn 从连接池获取连接
|
|
|
|
|
|
func (that *CacheRedis) getConn() redis.Conn {
|
|
|
|
|
|
that.initPool()
|
|
|
|
|
|
if that.pool == nil {
|
|
|
|
|
|
return nil
|
|
|
|
|
|
}
|
|
|
|
|
|
return that.pool.Get()
|
2018-04-04 18:44:00 +00:00
|
|
|
|
}
|
2026-01-22 04:36:52 +08:00
|
|
|
|
|
2022-03-13 01:48:54 +08:00
|
|
|
|
func (that *CacheRedis) del(key string) {
|
2026-01-22 04:36:52 +08:00
|
|
|
|
conn := that.getConn()
|
|
|
|
|
|
if conn == nil {
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
defer conn.Close()
|
|
|
|
|
|
|
2020-02-20 14:20:56 +08:00
|
|
|
|
del := strings.Index(key, "*")
|
|
|
|
|
|
if del != -1 {
|
2026-01-22 04:36:52 +08:00
|
|
|
|
val, err := redis.Strings(conn.Do("KEYS", key))
|
2020-02-20 14:20:56 +08:00
|
|
|
|
if err != nil {
|
2026-01-22 04:36:52 +08:00
|
|
|
|
that.Error.SetError(err)
|
2018-04-09 17:16:24 +00:00
|
|
|
|
return
|
|
|
|
|
|
}
|
2026-01-22 04:36:52 +08:00
|
|
|
|
if len(val) == 0 {
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
conn.Send("MULTI")
|
|
|
|
|
|
for i := range val {
|
|
|
|
|
|
conn.Send("DEL", val[i])
|
|
|
|
|
|
}
|
|
|
|
|
|
_, err = conn.Do("EXEC")
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
that.Error.SetError(err)
|
2018-04-09 17:16:24 +00:00
|
|
|
|
}
|
2020-02-20 14:20:56 +08:00
|
|
|
|
} else {
|
2026-01-22 04:36:52 +08:00
|
|
|
|
_, err := conn.Do("DEL", key)
|
2020-02-20 14:20:56 +08:00
|
|
|
|
if err != nil {
|
2022-03-13 01:48:54 +08:00
|
|
|
|
that.Error.SetError(err)
|
2018-04-09 17:16:24 +00:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2018-04-04 18:44:00 +00:00
|
|
|
|
|
2026-01-22 02:44:53 +08:00
|
|
|
|
// key value ,时间为时间戳
|
2026-01-22 04:36:52 +08:00
|
|
|
|
func (that *CacheRedis) set(key string, value string, expireSeconds int64) {
|
|
|
|
|
|
conn := that.getConn()
|
|
|
|
|
|
if conn == nil {
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
defer conn.Close()
|
2018-04-09 17:16:24 +00:00
|
|
|
|
|
2026-01-22 04:36:52 +08:00
|
|
|
|
_, err := conn.Do("SET", key, value, "EX", ObjToStr(expireSeconds))
|
|
|
|
|
|
if err != nil {
|
2022-03-13 01:48:54 +08:00
|
|
|
|
that.Error.SetError(err)
|
2018-04-09 17:16:24 +00:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2022-03-13 01:48:54 +08:00
|
|
|
|
func (that *CacheRedis) get(key string) *Obj {
|
2020-02-20 14:20:56 +08:00
|
|
|
|
reData := &Obj{}
|
2026-01-22 04:36:52 +08:00
|
|
|
|
conn := that.getConn()
|
|
|
|
|
|
if conn == nil {
|
|
|
|
|
|
return reData
|
|
|
|
|
|
}
|
|
|
|
|
|
defer conn.Close()
|
|
|
|
|
|
|
2018-04-04 18:44:00 +00:00
|
|
|
|
var err error
|
2026-01-22 04:36:52 +08:00
|
|
|
|
reData.Data, err = redis.String(conn.Do("GET", key))
|
2018-04-09 17:16:24 +00:00
|
|
|
|
if err != nil {
|
2020-02-20 14:20:56 +08:00
|
|
|
|
reData.Data = nil
|
2018-04-09 17:16:24 +00:00
|
|
|
|
if !strings.Contains(err.Error(), "nil returned") {
|
2022-03-13 01:48:54 +08:00
|
|
|
|
that.Error.SetError(err)
|
2018-04-09 17:16:24 +00:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
return reData
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2022-03-13 01:48:54 +08:00
|
|
|
|
func (that *CacheRedis) Cache(key string, data ...interface{}) *Obj {
|
2020-02-20 14:20:56 +08:00
|
|
|
|
reData := &Obj{}
|
2026-01-22 04:36:52 +08:00
|
|
|
|
|
2018-04-04 18:44:00 +00:00
|
|
|
|
//查询缓存
|
|
|
|
|
|
if len(data) == 0 {
|
2022-03-13 01:48:54 +08:00
|
|
|
|
reData = that.get(key)
|
2018-04-09 17:16:24 +00:00
|
|
|
|
return reData
|
2018-04-04 18:44:00 +00:00
|
|
|
|
}
|
2026-01-22 04:36:52 +08:00
|
|
|
|
|
2018-04-04 18:44:00 +00:00
|
|
|
|
tim := int64(0)
|
|
|
|
|
|
//删除缓存
|
|
|
|
|
|
if len(data) == 1 && data[0] == nil {
|
2022-03-13 01:48:54 +08:00
|
|
|
|
that.del(key)
|
2018-04-04 18:44:00 +00:00
|
|
|
|
return reData
|
|
|
|
|
|
}
|
|
|
|
|
|
//添加缓存
|
|
|
|
|
|
if len(data) == 1 {
|
2022-03-13 01:48:54 +08:00
|
|
|
|
if that.TimeOut == 0 {
|
|
|
|
|
|
//that.Time = Config.GetInt64("cacheShortTime")
|
2018-04-04 18:44:00 +00:00
|
|
|
|
}
|
2022-03-13 01:48:54 +08:00
|
|
|
|
tim += that.TimeOut
|
2018-04-04 18:44:00 +00:00
|
|
|
|
}
|
|
|
|
|
|
if len(data) == 2 {
|
2022-03-13 01:48:54 +08:00
|
|
|
|
that.Error.SetError(nil)
|
|
|
|
|
|
tempt := ObjToInt64(data[1], that.Error)
|
2018-06-13 11:10:13 +00:00
|
|
|
|
if tempt > tim {
|
|
|
|
|
|
tim = tempt
|
2022-03-13 01:48:54 +08:00
|
|
|
|
} else if that.GetError() == nil {
|
2018-06-13 11:10:13 +00:00
|
|
|
|
tim = tim + tempt
|
2018-04-04 18:44:00 +00:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2022-03-13 01:48:54 +08:00
|
|
|
|
that.set(key, ObjToStr(data[0]), tim)
|
2018-04-09 17:16:24 +00:00
|
|
|
|
|
2018-04-04 18:44:00 +00:00
|
|
|
|
return reData
|
|
|
|
|
|
}
|