cec151fd by astaxie

Merge pull request #674 from reterVision/master

Make redis cache timeout not trivial.
2 parents cbffcaa7 b6c4e27a
...@@ -35,11 +35,11 @@ type Cache interface { ...@@ -35,11 +35,11 @@ type Cache interface {
35 Incr(key string) error 35 Incr(key string) error
36 // decrease cached int value by key, as a counter. 36 // decrease cached int value by key, as a counter.
37 Decr(key string) error 37 Decr(key string) error
38 // check cached value is existed or not. 38 // check if cached value exists or not.
39 IsExist(key string) bool 39 IsExist(key string) bool
40 // clear all cache. 40 // clear all cache.
41 ClearAll() error 41 ClearAll() error
42 // start gc routine via config string setting. 42 // start gc routine based on config string settings.
43 StartAndGC(config string) error 43 StartAndGC(config string) error
44 } 44 }
45 45
...@@ -58,13 +58,13 @@ func Register(name string, adapter Cache) { ...@@ -58,13 +58,13 @@ func Register(name string, adapter Cache) {
58 adapters[name] = adapter 58 adapters[name] = adapter
59 } 59 }
60 60
61 // Create a new cache driver by adapter and config string. 61 // Create a new cache driver by adapter name and config string.
62 // config need to be correct JSON as string: {"interval":360}. 62 // config need to be correct JSON as string: {"interval":360}.
63 // it will start gc automatically. 63 // it will start gc automatically.
64 func NewCache(adapterName, config string) (Cache, error) { 64 func NewCache(adapterName, config string) (Cache, error) {
65 adapter, ok := adapters[adapterName] 65 adapter, ok := adapters[adapterName]
66 if !ok { 66 if !ok {
67 return nil, fmt.Errorf("cache: unknown adaptername %q (forgotten import?)", adapterName) 67 return nil, fmt.Errorf("cache: unknown adapter name %q (forgot to import?)", adapterName)
68 } 68 }
69 err := adapter.StartAndGC(config) 69 err := adapter.StartAndGC(config)
70 if err != nil { 70 if err != nil {
......
...@@ -47,7 +47,7 @@ func (rc *RedisCache) do(commandName string, args ...interface{}) (reply interfa ...@@ -47,7 +47,7 @@ func (rc *RedisCache) do(commandName string, args ...interface{}) (reply interfa
47 47
48 // Get cache from redis. 48 // Get cache from redis.
49 func (rc *RedisCache) Get(key string) interface{} { 49 func (rc *RedisCache) Get(key string) interface{} {
50 v, err := rc.do("HGET", rc.key, key) 50 v, err := rc.do("GET", key)
51 if err != nil { 51 if err != nil {
52 return nil 52 return nil
53 } 53 }
...@@ -56,43 +56,66 @@ func (rc *RedisCache) Get(key string) interface{} { ...@@ -56,43 +56,66 @@ func (rc *RedisCache) Get(key string) interface{} {
56 } 56 }
57 57
58 // put cache to redis. 58 // put cache to redis.
59 // timeout is ignored.
60 func (rc *RedisCache) Put(key string, val interface{}, timeout int64) error { 59 func (rc *RedisCache) Put(key string, val interface{}, timeout int64) error {
61 _, err := rc.do("HSET", rc.key, key, val) 60 _, err := rc.do("SET", key, val)
61 if err != nil {
62 return nil
63 }
64 _, err = rc.do("HSET", rc.key, key, true)
65 if err != nil {
66 return nil
67 }
68 _, err = rc.do("EXPIRE", key, timeout)
62 return err 69 return err
63 } 70 }
64 71
65 // delete cache in redis. 72 // delete cache in redis.
66 func (rc *RedisCache) Delete(key string) error { 73 func (rc *RedisCache) Delete(key string) error {
67 _, err := rc.do("HDEL", rc.key, key) 74 _, err := rc.do("DEL", key)
75 if err != nil {
76 return nil
77 }
78 _, err = rc.do("HDEL", rc.key, key)
68 return err 79 return err
69 } 80 }
70 81
71 // check cache exist in redis. 82 // check cache's existence in redis.
72 func (rc *RedisCache) IsExist(key string) bool { 83 func (rc *RedisCache) IsExist(key string) bool {
73 v, err := redis.Bool(rc.do("HEXISTS", rc.key, key)) 84 v, err := redis.Bool(rc.do("EXISTS", key))
74 if err != nil { 85 if err != nil {
75 return false 86 return false
76 } 87 }
77 88 if v == false {
89 _, err := rc.do("HDEL", rc.key, key)
90 if err != nil {
91 return false
92 }
93 }
78 return v 94 return v
79 } 95 }
80 96
81 // increase counter in redis. 97 // increase counter in redis.
82 func (rc *RedisCache) Incr(key string) error { 98 func (rc *RedisCache) Incr(key string) error {
83 _, err := redis.Bool(rc.do("HINCRBY", rc.key, key, 1)) 99 _, err := redis.Bool(rc.do("INCRBY", key, 1))
84 return err 100 return err
85 } 101 }
86 102
87 // decrease counter in redis. 103 // decrease counter in redis.
88 func (rc *RedisCache) Decr(key string) error { 104 func (rc *RedisCache) Decr(key string) error {
89 _, err := redis.Bool(rc.do("HINCRBY", rc.key, key, -1)) 105 _, err := redis.Bool(rc.do("INCRBY", key, -1))
90 return err 106 return err
91 } 107 }
92 108
93 // clean all cache in redis. delete this redis collection. 109 // clean all cache in redis. delete this redis collection.
94 func (rc *RedisCache) ClearAll() error { 110 func (rc *RedisCache) ClearAll() error {
95 _, err := rc.do("DEL", rc.key) 111 cachedKeys, err := redis.Strings(rc.do("HKEYS", rc.key))
112 for _, str := range cachedKeys {
113 _, err := rc.do("DEL", str)
114 if err != nil {
115 return nil
116 }
117 }
118 _, err = rc.do("DEL", rc.key)
96 return err 119 return err
97 } 120 }
98 121
......
1 // Beego (http://beego.me/)
2
3 // @description beego is an open-source, high-performance web framework for the Go programming language.
4
5 // @link http://github.com/astaxie/beego for the canonical source repository
6
7 // @license http://github.com/astaxie/beego/blob/master/LICENSE
8
9 // @authors astaxie
10
11 package cache
12
13 import (
14 "testing"
15 "time"
16
17 "github.com/beego/redigo/redis"
18
19 "github.com/astaxie/beego/cache"
20 )
21
22 func TestRedisCache(t *testing.T) {
23 bm, err := cache.NewCache("redis", `{"conn": "127.0.0.1:6379"}`)
24 if err != nil {
25 t.Error("init err")
26 }
27 if err = bm.Put("astaxie", 1, 10); err != nil {
28 t.Error("set Error", err)
29 }
30 if !bm.IsExist("astaxie") {
31 t.Error("check err")
32 }
33
34 time.Sleep(10 * time.Second)
35
36 if bm.IsExist("astaxie") {
37 t.Error("check err")
38 }
39 if err = bm.Put("astaxie", 1, 10); err != nil {
40 t.Error("set Error", err)
41 }
42
43 if v, _ := redis.Int(bm.Get("astaxie"), err); v != 1 {
44 t.Error("get err")
45 }
46
47 if err = bm.Incr("astaxie"); err != nil {
48 t.Error("Incr Error", err)
49 }
50
51 if v, _ := redis.Int(bm.Get("astaxie"), err); v != 2 {
52 t.Error("get err")
53 }
54
55 if err = bm.Decr("astaxie"); err != nil {
56 t.Error("Decr Error", err)
57 }
58
59 if v, _ := redis.Int(bm.Get("astaxie"), err); v != 1 {
60 t.Error("get err")
61 }
62 bm.Delete("astaxie")
63 if bm.IsExist("astaxie") {
64 t.Error("delete err")
65 }
66 //test string
67 if err = bm.Put("astaxie", "author", 10); err != nil {
68 t.Error("set Error", err)
69 }
70 if !bm.IsExist("astaxie") {
71 t.Error("check err")
72 }
73
74 if v, _ := redis.String(bm.Get("astaxie"), err); v != "author" {
75 t.Error("get err")
76 }
77 // test clear all
78 if err = bm.ClearAll(); err != nil {
79 t.Error("clear all err")
80 }
81 }
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!