beego cache模块源码分析笔记三

2018-12-26  本文已影响39人  ljh123
image.png

从代码库中可以看到有两个文件,其中有一个是测试文件。
整个代码包括注释一共两百多行代码。

整个代码提供给开发者的内容分为以下几个部分:
(1)变量
(2)结构体

初始化:

func init() {
    cache.Register("redis", NewRedisCache)
}

一、变量
DefaultKey

var (
    DefaultKey = "beecacheRedis"
)

2、结构体
(1)Cache
源码:

type Cache struct {
    p        *redis.Pool // redis connection pool
    conninfo string
    dbNum    int
    key      string
    password string
    maxIdle  int
}

相关函数:
(1)func NewRedisCache() cache.Cache

func NewRedisCache() cache.Cache {
    return &Cache{key: DefaultKey}
}

创建一个RedisCache对象
(2)func (rc *Cache) do(commandName string, args ...interface{}) (reply interface{}, err error)

func (rc *Cache) do(commandName string, args ...interface{}) (reply interface{}, err error) {
    if len(args) < 1 {
        return nil, errors.New("missing required arguments")
    }
    args[0] = rc.associate(args[0])
    c := rc.p.Get()
    defer c.Close()

    return c.Do(commandName, args...)
}

func (rc *Cache) associate(originKey interface{}) string {
    return fmt.Sprintf("%s:%s", rc.key, originKey)
}

发送命令到redis服务器
(3)func (rc *Cache) Get(key string) interface{}

func (rc *Cache) Get(key string) interface{} {
    if v, err := rc.do("GET", key); err == nil {
        return v
    }
    return nil
}

从redis服务器读取一个值
(4)func (rc *Cache) GetMulti(keys []string) []interface{}

func (rc *Cache) GetMulti(keys []string) []interface{} {
    c := rc.p.Get()
    defer c.Close()
    var args []interface{}
    for _, key := range keys {
        args = append(args, rc.associate(key))
    }
    values, err := redis.Values(c.Do("MGET", args...))
    if err != nil {
        return nil
    }
    return values
}

从redis服务器读取多个值
(5)func (rc *Cache) Put(key string, val interface{}, timeout time.Duration) error

func (rc *Cache) Put(key string, val interface{}, timeout time.Duration) error {
    _, err := rc.do("SETEX", key, int64(timeout/time.Second), val)
    return err
}

设置值
(6)func (rc *Cache) Delete(key string) error

func (rc *Cache) Delete(key string) error {
    _, err := rc.do("DEL", key)
    return err
}

删除键值
(7)func (rc *Cache) IsExist(key string) bool

func (rc *Cache) IsExist(key string) bool {
    v, err := redis.Bool(rc.do("EXISTS", key))
    if err != nil {
        return false
    }
    return v
}

判断是否存在
(8)func (rc *Cache) Incr(key string) error

func (rc *Cache) Incr(key string) error {
    _, err := redis.Bool(rc.do("INCRBY", key, 1))
    return err
}

值自加一
(9)func (rc *Cache) Decr(key string) error

func (rc *Cache) Decr(key string) error {
    _, err := redis.Bool(rc.do("INCRBY", key, -1))
    return err
}

值自减一
(10)func (rc *Cache) ClearAll() error

func (rc *Cache) ClearAll() error {
    c := rc.p.Get()
    defer c.Close()
    cachedKeys, err := redis.Strings(c.Do("KEYS", rc.key+":*"))
    if err != nil {
        return err
    }
    for _, str := range cachedKeys {
        if _, err = c.Do("DEL", str); err != nil {
            return err
        }
    }
    return err
}

清除内容
(11)func (rc *Cache) StartAndGC(config string) error

func (rc *Cache) StartAndGC(config string) error {
    var cf map[string]string
    json.Unmarshal([]byte(config), &cf)

    if _, ok := cf["key"]; !ok {
        cf["key"] = DefaultKey
    }
    if _, ok := cf["conn"]; !ok {
        return errors.New("config has no conn key")
    }

    // Format redis://<password>@<host>:<port>
    cf["conn"] = strings.Replace(cf["conn"], "redis://", "", 1)
    if i := strings.Index(cf["conn"], "@"); i > -1 {
        cf["password"] = cf["conn"][0:i]
        cf["conn"] = cf["conn"][i+1:]
    }

    if _, ok := cf["dbNum"]; !ok {
        cf["dbNum"] = "0"
    }
    if _, ok := cf["password"]; !ok {
        cf["password"] = ""
    }
    if _, ok := cf["maxIdle"]; !ok {
        cf["maxIdle"] = "3"
    }
    rc.key = cf["key"]
    rc.conninfo = cf["conn"]
    rc.dbNum, _ = strconv.Atoi(cf["dbNum"])
    rc.password = cf["password"]
    rc.maxIdle, _ = strconv.Atoi(cf["maxIdle"])

    rc.connectInit()

    c := rc.p.Get()
    defer c.Close()

    return c.Err()
}

(12)func (rc *Cache) connectInit()

func (rc *Cache) connectInit() {
    dialFunc := func() (c redis.Conn, err error) {
        c, err = redis.Dial("tcp", rc.conninfo)
        if err != nil {
            return nil, err
        }

        if rc.password != "" {
            if _, err := c.Do("AUTH", rc.password); err != nil {
                c.Close()
                return nil, err
            }
        }

        _, selecterr := c.Do("SELECT", rc.dbNum)
        if selecterr != nil {
            c.Close()
            return nil, selecterr
        }
        return
    }
    // initialize a new pool
    rc.p = &redis.Pool{
        MaxIdle:     rc.maxIdle,
        IdleTimeout: 180 * time.Second,
        Dial:        dialFunc,
    }
}
上一篇 下一篇

猜你喜欢

热点阅读