未验证 提交 fd48c628 编写于 作者: J jianzhiyao 提交者: GitHub

Merge pull request #4316 from AllenX2018/fix-issue-4311

fix issue #4311
...@@ -120,6 +120,20 @@ func TestCache(t *testing.T) { ...@@ -120,6 +120,20 @@ func TestCache(t *testing.T) {
if vv[1].(string) != "author1" { if vv[1].(string) != "author1" {
t.Error("GetMulti ERROR") t.Error("GetMulti ERROR")
} }
vv, err = bm.GetMulti(context.Background(), []string{"astaxie0", "astaxie1"})
if len(vv) != 2 {
t.Error("GetMulti ERROR")
}
if vv[0] != nil {
t.Error("GetMulti ERROR")
}
if vv[1].(string) != "author1" {
t.Error("GetMulti ERROR")
}
if err != nil && err.Error() != "key [astaxie0] error: the key isn't exist" {
t.Error("GetMulti ERROR")
}
} }
func TestFileCache(t *testing.T) { func TestFileCache(t *testing.T) {
...@@ -189,5 +203,19 @@ func TestFileCache(t *testing.T) { ...@@ -189,5 +203,19 @@ func TestFileCache(t *testing.T) {
t.Error("GetMulti ERROR") t.Error("GetMulti ERROR")
} }
vv, err = bm.GetMulti(context.Background(), []string{"astaxie0", "astaxie1"})
if len(vv) != 2 {
t.Error("GetMulti ERROR")
}
if vv[0] != nil {
t.Error("GetMulti ERROR")
}
if vv[1].(string) != "author1" {
t.Error("GetMulti ERROR")
}
if err == nil {
t.Error("GetMulti ERROR")
}
os.RemoveAll("cache") os.RemoveAll("cache")
} }
...@@ -28,6 +28,7 @@ import ( ...@@ -28,6 +28,7 @@ import (
"path/filepath" "path/filepath"
"reflect" "reflect"
"strconv" "strconv"
"strings"
"time" "time"
"github.com/pkg/errors" "github.com/pkg/errors"
...@@ -144,17 +145,22 @@ func (fc *FileCache) Get(ctx context.Context, key string) (interface{}, error) { ...@@ -144,17 +145,22 @@ func (fc *FileCache) Get(ctx context.Context, key string) (interface{}, error) {
// GetMulti gets values from file cache. // GetMulti gets values from file cache.
// if nonexistent or expired return an empty string. // if nonexistent or expired return an empty string.
func (fc *FileCache) GetMulti(ctx context.Context, keys []string) ([]interface{}, error) { func (fc *FileCache) GetMulti(ctx context.Context, keys []string) ([]interface{}, error) {
var rc []interface{} rc := make([]interface{}, len(keys))
for _, key := range keys { keysErr := make([]string, 0)
val, err := fc.Get(context.Background(), key)
for i, ki := range keys {
val, err := fc.Get(context.Background(), ki)
if err != nil { if err != nil {
rc = append(rc, err) keysErr = append(keysErr, fmt.Sprintf("key [%s] error: %s", ki, err.Error()))
} else { continue
rc = append(rc, val)
} }
rc[i] = val
}
if len(keysErr) == 0 {
return rc, nil
} }
return rc, nil return rc, errors.New(strings.Join(keysErr, "; "))
} }
// Put value into file cache. // Put value into file cache.
......
...@@ -33,6 +33,7 @@ import ( ...@@ -33,6 +33,7 @@ import (
"context" "context"
"encoding/json" "encoding/json"
"errors" "errors"
"fmt"
"strings" "strings"
"time" "time"
...@@ -68,19 +69,31 @@ func (rc *Cache) Get(ctx context.Context, key string) (interface{}, error) { ...@@ -68,19 +69,31 @@ func (rc *Cache) Get(ctx context.Context, key string) (interface{}, error) {
// GetMulti gets a value from a key in memcache. // GetMulti gets a value from a key in memcache.
func (rc *Cache) GetMulti(ctx context.Context, keys []string) ([]interface{}, error) { func (rc *Cache) GetMulti(ctx context.Context, keys []string) ([]interface{}, error) {
var rv []interface{} rv := make([]interface{}, len(keys))
if rc.conn == nil { if rc.conn == nil {
if err := rc.connectInit(); err != nil { if err := rc.connectInit(); err != nil {
return rv, err return rv, err
} }
} }
mv, err := rc.conn.GetMulti(keys) mv, err := rc.conn.GetMulti(keys)
if err == nil { if err != nil {
for _, v := range mv { return rv, err
rv = append(rv, v.Value) }
keysErr := make([]string, 0)
for i, ki := range keys {
if _, ok := mv[ki]; !ok {
keysErr = append(keysErr, fmt.Sprintf("key [%s] error: %s", ki, "the key isn't exist"))
continue
} }
rv[i] = mv[ki].Value
}
if len(keysErr) == 0 {
return rv, nil
} }
return rv, err return rv, fmt.Errorf(strings.Join(keysErr, "; "))
} }
// Put puts a value into memcache. // Put puts a value into memcache.
......
...@@ -28,7 +28,6 @@ import ( ...@@ -28,7 +28,6 @@ import (
) )
func TestMemcacheCache(t *testing.T) { func TestMemcacheCache(t *testing.T) {
addr := os.Getenv("MEMCACHE_ADDR") addr := os.Getenv("MEMCACHE_ADDR")
if addr == "" { if addr == "" {
addr = "127.0.0.1:11211" addr = "127.0.0.1:11211"
...@@ -114,6 +113,20 @@ func TestMemcacheCache(t *testing.T) { ...@@ -114,6 +113,20 @@ func TestMemcacheCache(t *testing.T) {
t.Error("GetMulti ERROR") t.Error("GetMulti ERROR")
} }
vv, err = bm.GetMulti(context.Background(), []string{"astaxie0", "astaxie1"})
if len(vv) != 2 {
t.Error("GetMulti ERROR")
}
if vv[0] != nil {
t.Error("GetMulti ERROR")
}
if string(vv[1].([]byte)) != "author1" {
t.Error("GetMulti ERROR")
}
if err != nil && err.Error() == "key [astaxie0] error: key isn't exist" {
t.Error("GetMulti ERROR")
}
// test clear all // test clear all
if err = bm.ClearAll(context.Background()); err != nil { if err = bm.ClearAll(context.Background()); err != nil {
t.Error("clear all err") t.Error("clear all err")
......
...@@ -18,6 +18,8 @@ import ( ...@@ -18,6 +18,8 @@ import (
"context" "context"
"encoding/json" "encoding/json"
"errors" "errors"
"fmt"
"strings"
"sync" "sync"
"time" "time"
) )
...@@ -68,22 +70,28 @@ func (bc *MemoryCache) Get(ctx context.Context, key string) (interface{}, error) ...@@ -68,22 +70,28 @@ func (bc *MemoryCache) Get(ctx context.Context, key string) (interface{}, error)
} }
return itm.val, nil return itm.val, nil
} }
return nil, nil return nil, errors.New("the key isn't exist")
} }
// GetMulti gets caches from memory. // GetMulti gets caches from memory.
// If non-existent or expired, return nil. // If non-existent or expired, return nil.
func (bc *MemoryCache) GetMulti(ctx context.Context, keys []string) ([]interface{}, error) { func (bc *MemoryCache) GetMulti(ctx context.Context, keys []string) ([]interface{}, error) {
var rc []interface{} rc := make([]interface{}, len(keys))
for _, name := range keys { keysErr := make([]string, 0)
val, err := bc.Get(context.Background(), name)
for i, ki := range keys {
val, err := bc.Get(context.Background(), ki)
if err != nil { if err != nil {
rc = append(rc, err) keysErr = append(keysErr, fmt.Sprintf("key [%s] error: %s", ki, err.Error()))
} else { continue
rc = append(rc, val)
} }
rc[i] = val
}
if len(keysErr) == 0 {
return rc, nil
} }
return rc, nil return rc, errors.New(strings.Join(keysErr, "; "))
} }
// Put puts cache into memory. // Put puts cache into memory.
......
...@@ -113,6 +113,14 @@ func TestRedisCache(t *testing.T) { ...@@ -113,6 +113,14 @@ func TestRedisCache(t *testing.T) {
t.Error("GetMulti ERROR") t.Error("GetMulti ERROR")
} }
vv, _ = bm.GetMulti(context.Background(), []string{"astaxie0", "astaxie1"})
if vv[0] != nil {
t.Error("GetMulti ERROR")
}
if v, _ := redis.String(vv[1], nil); v != "author1" {
t.Error("GetMulti ERROR")
}
// test clear all // test clear all
if err = bm.ClearAll(context.Background()); err != nil { if err = bm.ClearAll(context.Background()); err != nil {
t.Error("clear all err") t.Error("clear all err")
......
...@@ -4,6 +4,7 @@ import ( ...@@ -4,6 +4,7 @@ import (
"context" "context"
"encoding/json" "encoding/json"
"errors" "errors"
"fmt"
"strconv" "strconv"
"strings" "strings"
"time" "time"
...@@ -41,23 +42,37 @@ func (rc *Cache) Get(ctx context.Context, key string) (interface{}, error) { ...@@ -41,23 +42,37 @@ func (rc *Cache) Get(ctx context.Context, key string) (interface{}, error) {
// GetMulti gets one or keys values from ssdb. // GetMulti gets one or keys values from ssdb.
func (rc *Cache) GetMulti(ctx context.Context, keys []string) ([]interface{}, error) { func (rc *Cache) GetMulti(ctx context.Context, keys []string) ([]interface{}, error) {
size := len(keys) size := len(keys)
var values []interface{} values := make([]interface{}, size)
if rc.conn == nil { if rc.conn == nil {
if err := rc.connectInit(); err != nil { if err := rc.connectInit(); err != nil {
return values, err return values, err
} }
} }
res, err := rc.conn.Do("multi_get", keys) res, err := rc.conn.Do("multi_get", keys)
if err != nil {
return values, err
}
resSize := len(res) resSize := len(res)
if err == nil { keyIdx := make(map[string]int)
for i := 1; i < resSize; i += 2 { for i := 1; i < resSize; i += 2 {
values = append(values, res[i+1]) keyIdx[res[i]] = i
}
keysErr := make([]string, 0)
for i, ki := range keys {
if _, ok := keyIdx[ki]; !ok {
keysErr = append(keysErr, fmt.Sprintf("key [%s] error: %s", ki, "the key isn't exist"))
continue
} }
return values, nil values[i] = res[keyIdx[ki]+1]
} }
for i := 0; i < size; i++ {
values = append(values, err) if len(keysErr) != 0 {
return values, fmt.Errorf(strings.Join(keysErr, "; "))
} }
return values, nil return values, nil
} }
......
...@@ -106,6 +106,20 @@ func TestSsdbcacheCache(t *testing.T) { ...@@ -106,6 +106,20 @@ func TestSsdbcacheCache(t *testing.T) {
t.Error("getmulti error") t.Error("getmulti error")
} }
vv, err = ssdb.GetMulti(context.Background(), []string{"ssdb", "ssdb11"})
if len(vv) != 2 {
t.Error("getmulti error")
}
if vv[0].(string) != "ssdb" {
t.Error("getmulti error")
}
if vv[1] != nil {
t.Error("getmulti error")
}
if err != nil && err.Error() != "key [ssdb11] error: the key isn't exist" {
t.Error("getmulti error")
}
// test clear all done // test clear all done
if err = ssdb.ClearAll(context.Background()); err != nil { if err = ssdb.ClearAll(context.Background()); err != nil {
t.Error("clear all err") t.Error("clear all err")
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册