Quellcode durchsuchen

Merge pull request #35 from silenceper/develop

1.增加redis支持 2.memcached支持多类型缓存
silenceper vor 8 Jahren
Ursprung
Commit
71fb38b9ca
4 geänderte Dateien mit 154 neuen und 11 gelöschten Zeilen
  1. 1 0
      .travis.yml
  2. 17 11
      cache/memcache.go
  3. 104 0
      cache/redis.go
  4. 32 0
      cache/redis_test.go

+ 1 - 0
.travis.yml

@@ -7,6 +7,7 @@ go:
 
 services:
   - memcached
+  - redis-server
 
 script:
     - go test -v ./...

+ 17 - 11
cache/memcache.go

@@ -1,7 +1,7 @@
 package cache
 
 import (
-	"errors"
+	"encoding/json"
 	"time"
 
 	"github.com/bradfitz/gomemcache/memcache"
@@ -20,28 +20,34 @@ func NewMemcache(server ...string) *Memcache {
 
 //Get return cached value
 func (mem *Memcache) Get(key string) interface{} {
-	if item, err := mem.conn.Get(key); err == nil {
-		return string(item.Value)
+	var err error
+	var item *memcache.Item
+	if item, err = mem.conn.Get(key); err != nil {
+		return nil
 	}
-	return nil
+	var result interface{}
+	if err = json.Unmarshal(item.Value, &result); err != nil {
+		return nil
+	}
+	return result
 }
 
 // IsExist check value exists in memcache.
 func (mem *Memcache) IsExist(key string) bool {
-	_, err := mem.conn.Get(key)
-	if err != nil {
+	if _, err := mem.conn.Get(key); err != nil {
 		return false
 	}
 	return true
 }
 
 //Set cached value with key and expire time.
-func (mem *Memcache) Set(key string, val interface{}, timeout time.Duration) error {
-	v, ok := val.(string)
-	if !ok {
-		return errors.New("val must string")
+func (mem *Memcache) Set(key string, val interface{}, timeout time.Duration) (err error) {
+	var data []byte
+	if data, err = json.Marshal(val); err != nil {
+		return err
 	}
-	item := &memcache.Item{Key: key, Value: []byte(v), Expiration: int32(timeout / time.Second)}
+
+	item := &memcache.Item{Key: key, Value: data, Expiration: int32(timeout / time.Second)}
 	return mem.conn.Set(item)
 }
 

+ 104 - 0
cache/redis.go

@@ -0,0 +1,104 @@
+package cache
+
+import (
+	"encoding/json"
+	"time"
+
+	"github.com/garyburd/redigo/redis"
+)
+
+//Redis redis cache
+type Redis struct {
+	conn *redis.Pool
+}
+
+//RedisOpts redis 连接属性
+type RedisOpts struct {
+	Host        string
+	Password    string
+	Database    int
+	MaxIdle     int
+	MaxActive   int
+	IdleTimeout time.Duration //second
+}
+
+//NewRedis 实例化
+func NewRedis(opts *RedisOpts) *Redis {
+	pool := &redis.Pool{
+		MaxActive:   opts.MaxActive,
+		MaxIdle:     opts.MaxIdle,
+		IdleTimeout: opts.IdleTimeout,
+		Dial: func() (redis.Conn, error) {
+			return redis.Dial("tcp", opts.Host,
+				redis.DialDatabase(opts.Database),
+				redis.DialPassword(opts.Password),
+			)
+		},
+		TestOnBorrow: func(conn redis.Conn, t time.Time) error {
+			if time.Since(t) < time.Minute {
+				return nil
+			}
+			_, err := conn.Do("PING")
+			return err
+		},
+	}
+	return &Redis{pool}
+}
+
+//Get 获取一个值
+func (r *Redis) Get(key string) interface{} {
+	conn := r.conn.Get()
+	defer conn.Close()
+
+	var data []byte
+	var err error
+	if data, err = redis.Bytes(conn.Do("GET", key)); err != nil {
+		return nil
+	}
+	var reply interface{}
+	if err = json.Unmarshal(data, &reply); err != nil {
+		return nil
+	}
+
+	return reply
+}
+
+//Set 设置一个值
+func (r *Redis) Set(key string, val interface{}, timeout time.Duration) (err error) {
+	conn := r.conn.Get()
+	defer conn.Close()
+
+	var data []byte
+	if data, err = json.Marshal(val); err != nil {
+		return
+	}
+
+	_, err = conn.Do("SETEX", key, int64(timeout/time.Second), data)
+
+	return
+}
+
+//IsExist 判断key是否存在
+func (r *Redis) IsExist(key string) bool {
+	conn := r.conn.Get()
+	defer conn.Close()
+
+	a, _ := conn.Do("EXISTS", key)
+	i := a.(int64)
+	if i > 0 {
+		return true
+	}
+	return false
+}
+
+//Delete 删除
+func (r *Redis) Delete(key string) error {
+	conn := r.conn.Get()
+	defer conn.Close()
+
+	if _, err := conn.Do("DEL", key); err != nil {
+		return err
+	}
+
+	return nil
+}

+ 32 - 0
cache/redis_test.go

@@ -0,0 +1,32 @@
+package cache
+
+import (
+	"testing"
+	"time"
+)
+
+func TestRedis(t *testing.T) {
+	opts := &RedisOpts{
+		Host: "127.0.0.1:6379",
+	}
+	redis := NewRedis(opts)
+	var err error
+	timeoutDuration := 1 * time.Second
+
+	if err = redis.Set("username", "silenceper", timeoutDuration); err != nil {
+		t.Error("set Error", err)
+	}
+
+	if !redis.IsExist("username") {
+		t.Error("IsExist Error")
+	}
+
+	name := redis.Get("username").(string)
+	if name != "silenceper" {
+		t.Error("get Error")
+	}
+
+	if err = redis.Delete("username"); err != nil {
+		t.Errorf("delete Error , err=%v", err)
+	}
+}