From 6eee72b3360752c12ec47f1c9cfa2fa1c5830ea1 Mon Sep 17 00:00:00 2001 From: John Guo Date: Thu, 23 Sep 2021 21:23:22 +0800 Subject: [PATCH] refract package gredis --- database/gredis/gredis.go | 65 ---- database/gredis/gredis_adapter_redigo.go | 5 +- database/gredis/gredis_adapter_redigo_conn.go | 2 +- database/gredis/gredis_config.go | 16 + database/gredis/gredis_instance.go | 13 +- database/gredis/gredis_redis.go | 86 +++++ database/gredis/gredis_redis_conn.go | 38 +++ database/gredis/gredis_utils.go | 25 ++ database/gredis/gredis_z_unit_conn_test.go | 29 +- database/gredis/gredis_z_unit_test.go | 302 ++++++++++-------- os/gsession/gsession_session.go | 2 +- .../gsession_storage_redis_hashtable.go | 15 +- ...ssion_unit_storage_redis_hashtable_test.go | 8 +- .../gsession_unit_storage_redis_test.go | 6 +- 14 files changed, 389 insertions(+), 223 deletions(-) create mode 100644 database/gredis/gredis_redis.go create mode 100644 database/gredis/gredis_redis_conn.go create mode 100644 database/gredis/gredis_utils.go diff --git a/database/gredis/gredis.go b/database/gredis/gredis.go index 4faaf91d9..75d338407 100644 --- a/database/gredis/gredis.go +++ b/database/gredis/gredis.go @@ -14,33 +14,10 @@ package gredis import ( - "context" - "github.com/gogf/gf/container/gvar" "github.com/gogf/gf/errors/gcode" "github.com/gogf/gf/errors/gerror" - "time" ) -// Redis client. -type Redis struct { - adapter Adapter -} - -// Config is redis configuration. -type Config struct { - Host string `json:"host"` - Port int `json:"port"` - Db int `json:"db"` - Pass string `json:"pass"` // Password for AUTH. - MaxIdle int `json:"maxIdle"` // Maximum number of connections allowed to be idle (default is 10) - MaxActive int `json:"maxActive"` // Maximum number of connections limit (default is 0 means no limit). - IdleTimeout time.Duration `json:"idleTimeout"` // Maximum idle time for connection (default is 10 seconds, not allowed to be set to 0) - MaxConnLifetime time.Duration `json:"maxConnLifetime"` // Maximum lifetime of the connection (default is 30 seconds, not allowed to be set to 0) - ConnectTimeout time.Duration `json:"connectTimeout"` // Dial connection timeout. - TLS bool `json:"tls"` // Specifies the config to use when a TLS connection is dialed. - TLSSkipVerify bool `json:"tlsSkipVerify"` // Disables server name verification when connecting over TLS. -} - func New(config ...*Config) (*Redis, error) { if len(config) > 0 { return &Redis{adapter: NewAdapterRedigo(config[0])}, nil @@ -58,45 +35,3 @@ func New(config ...*Config) (*Redis, error) { func NewWithAdapter(adapter Adapter) *Redis { return &Redis{adapter: adapter} } - -func (r *Redis) SetAdapter(adapter Adapter) { - r.adapter = adapter -} - -// Conn returns a raw underlying connection object, -// which expose more methods to communicate with server. -// **You should call Close function manually if you do not use this connection any further.** -func (r *Redis) Conn(ctx context.Context) (Conn, error) { - return r.adapter.Conn(ctx) -} - -// Stats returns pool's statistics. -func (r *Redis) Stats(ctx context.Context) (Stats, error) { - return r.adapter.Stats(ctx) -} - -// Do sends a command to the server and returns the received reply. -// Do automatically get a connection from pool, and close it when the reply received. -// It does not really "close" the connection, but drops it back to the connection pool. -func (r *Redis) Do(ctx context.Context, command string, args ...interface{}) (*gvar.Var, error) { - conn, err := r.Conn(ctx) - if err != nil { - return nil, err - } - defer conn.Close(ctx) - - if len(args) > 0 { - lastElement := args[len(args)-1] - switch option := lastElement.(type) { - case Option: - return conn.Do(ctx, command, args, &option) - - case *Option: - return conn.Do(ctx, command, args, option) - - default: - return conn.Do(ctx, command, args, nil) - } - } - return conn.Do(ctx, command, args, nil) -} diff --git a/database/gredis/gredis_adapter_redigo.go b/database/gredis/gredis_adapter_redigo.go index b0394fb83..35e0265bb 100644 --- a/database/gredis/gredis_adapter_redigo.go +++ b/database/gredis/gredis_adapter_redigo.go @@ -28,7 +28,6 @@ import ( type AdapterRedigo struct { pool *redis.Pool // Underlying connection pool. config *Config // Configuration. - group string // Configuration group. } const ( @@ -86,12 +85,12 @@ func NewAdapterRedigo(config *Config) *AdapterRedigo { intlog.Printf(context.TODO(), `open new connection, config:%+v`, config) // AUTH if len(config.Pass) > 0 { - if _, err := c.Do("AUTH", config.Pass); err != nil { + if _, err = c.Do("AUTH", config.Pass); err != nil { return nil, err } } // DB - if _, err := c.Do("SELECT", config.Db); err != nil { + if _, err = c.Do("SELECT", config.Db); err != nil { return nil, err } return c, nil diff --git a/database/gredis/gredis_adapter_redigo_conn.go b/database/gredis/gredis_adapter_redigo_conn.go index e5683ec62..36cdf2a47 100644 --- a/database/gredis/gredis_adapter_redigo_conn.go +++ b/database/gredis/gredis_adapter_redigo_conn.go @@ -68,7 +68,7 @@ func (c *localAdapterRedisConn) Do(ctx context.Context, command string, args []i // Receive receives a single reply as gvar.Var from the Redis server. func (c *localAdapterRedisConn) Receive(ctx context.Context, option *Option) (*gvar.Var, error) { if option == nil { - option = &Option{} + option = defaultOption() } return resultToVar(c.ReceiveWithTimeout(option.ReadTimeout)) } diff --git a/database/gredis/gredis_config.go b/database/gredis/gredis_config.go index 30a0af7e6..77a3cc30a 100644 --- a/database/gredis/gredis_config.go +++ b/database/gredis/gredis_config.go @@ -11,6 +11,7 @@ import ( "github.com/gogf/gf/errors/gcode" "github.com/gogf/gf/errors/gerror" "github.com/gogf/gf/internal/intlog" + "time" "github.com/gogf/gf/container/gmap" "github.com/gogf/gf/text/gregex" @@ -18,6 +19,21 @@ import ( "github.com/gogf/gf/util/gconv" ) +// Config is redis configuration. +type Config struct { + Host string `json:"host"` + Port int `json:"port"` + Db int `json:"db"` + Pass string `json:"pass"` // Password for AUTH. + MaxIdle int `json:"maxIdle"` // Maximum number of connections allowed to be idle (default is 10) + MaxActive int `json:"maxActive"` // Maximum number of connections limit (default is 0 means no limit). + IdleTimeout time.Duration `json:"idleTimeout"` // Maximum idle time for connection (default is 10 seconds, not allowed to be set to 0) + MaxConnLifetime time.Duration `json:"maxConnLifetime"` // Maximum lifetime of the connection (default is 30 seconds, not allowed to be set to 0) + ConnectTimeout time.Duration `json:"connectTimeout"` // Dial connection timeout. + TLS bool `json:"tls"` // Specifies the config to use when a TLS connection is dialed. + TLSSkipVerify bool `json:"tlsSkipVerify"` // Disables server name verification when connecting over TLS. +} + const ( DefaultGroupName = "default" // Default configuration group name. DefaultRedisPort = 6379 // Default redis port configuration if not passed. diff --git a/database/gredis/gredis_instance.go b/database/gredis/gredis_instance.go index 47aeb1b14..41be7ffd2 100644 --- a/database/gredis/gredis_instance.go +++ b/database/gredis/gredis_instance.go @@ -6,7 +6,11 @@ package gredis -import "github.com/gogf/gf/container/gmap" +import ( + "context" + "github.com/gogf/gf/container/gmap" + "github.com/gogf/gf/internal/intlog" +) var ( // Instance map @@ -23,8 +27,11 @@ func Instance(name ...string) *Redis { } v := instances.GetOrSetFuncLock(group, func() interface{} { if config, ok := GetConfig(group); ok { - r := NewAdapterRedigo(config) - r.group = group + r, err := New(config) + if err != nil { + intlog.Error(context.TODO(), err) + return nil + } return r } return nil diff --git a/database/gredis/gredis_redis.go b/database/gredis/gredis_redis.go new file mode 100644 index 000000000..30c3801e4 --- /dev/null +++ b/database/gredis/gredis_redis.go @@ -0,0 +1,86 @@ +// Copyright GoFrame Author(https://goframe.org). All Rights Reserved. +// +// This Source Code Form is subject to the terms of the MIT License. +// If a copy of the MIT was not distributed with this file, +// You can obtain one at https://github.com/gogf/gf. + +package gredis + +import ( + "context" + "github.com/gogf/gf/container/gvar" + "github.com/gogf/gf/errors/gcode" + "github.com/gogf/gf/errors/gerror" + "github.com/gogf/gf/internal/intlog" +) + +// Redis client. +type Redis struct { + adapter Adapter +} + +const ( + errorNilRedis = `the Redis object is nil` +) + +func (r *Redis) SetAdapter(adapter Adapter) { + if r == nil { + return + } + r.adapter = adapter +} + +func (r *Redis) GetAdapter() Adapter { + if r == nil { + return nil + } + return r.adapter +} + +// Conn returns a raw underlying connection object, +// which expose more methods to communicate with server. +// **You should call Close function manually if you do not use this connection any further.** +func (r *Redis) Conn(ctx context.Context) (*RedisConn, error) { + if r == nil { + return nil, gerror.NewCode(gcode.CodeInvalidParameter, errorNilRedis) + } + conn, err := r.adapter.Conn(ctx) + if err != nil { + return nil, err + } + return &RedisConn{conn: conn}, nil +} + +// Stats returns pool's statistics. +func (r *Redis) Stats(ctx context.Context) (Stats, error) { + if r == nil { + return nil, gerror.NewCode(gcode.CodeInvalidParameter, errorNilRedis) + } + return r.adapter.Stats(ctx) +} + +// Do sends a command to the server and returns the received reply. +// Do automatically get a connection from pool, and close it when the reply received. +// It does not really "close" the connection, but drops it back to the connection pool. +func (r *Redis) Do(ctx context.Context, command string, args ...interface{}) (*gvar.Var, error) { + if r == nil { + return nil, gerror.NewCode(gcode.CodeInvalidParameter, errorNilRedis) + } + conn, err := r.Conn(ctx) + if err != nil { + return nil, err + } + defer func() { + if err := conn.Close(ctx); err != nil { + intlog.Error(ctx, err) + } + }() + return conn.Do(ctx, command, args...) +} + +func (r *Redis) Close(ctx context.Context) error { + if r == nil { + return gerror.NewCode(gcode.CodeInvalidParameter, errorNilRedis) + } + return r.adapter.Close(ctx) +} diff --git a/database/gredis/gredis_redis_conn.go b/database/gredis/gredis_redis_conn.go new file mode 100644 index 000000000..b0f55c02f --- /dev/null +++ b/database/gredis/gredis_redis_conn.go @@ -0,0 +1,38 @@ +// Copyright GoFrame Author(https://goframe.org). All Rights Reserved. +// +// This Source Code Form is subject to the terms of the MIT License. +// If a copy of the MIT was not distributed with this file, +// You can obtain one at https://github.com/gogf/gf. + +package gredis + +import ( + "context" + "github.com/gogf/gf/container/gvar" +) + +type RedisConn struct { + conn Conn +} + +func (c *RedisConn) Do(ctx context.Context, command string, args ...interface{}) (reply *gvar.Var, err error) { + args, option := parseArgsToArgsAndOption(args) + return c.conn.Do(ctx, command, args, option) +} + +// Receive receives a single reply as gvar.Var from the Redis server. +func (c *RedisConn) Receive(ctx context.Context, option ...*Option) (*gvar.Var, error) { + var ( + usedOption *Option + ) + if len(option) > 0 { + usedOption = option[0] + } else { + usedOption = defaultOption() + } + return c.conn.Receive(ctx, usedOption) +} + +func (c *RedisConn) Close(ctx context.Context) error { + return c.conn.Close(ctx) +} diff --git a/database/gredis/gredis_utils.go b/database/gredis/gredis_utils.go new file mode 100644 index 000000000..0a9907109 --- /dev/null +++ b/database/gredis/gredis_utils.go @@ -0,0 +1,25 @@ +// Copyright GoFrame Author(https://goframe.org). All Rights Reserved. +// +// This Source Code Form is subject to the terms of the MIT License. +// If a copy of the MIT was not distributed with this file, +// You can obtain one at https://github.com/gogf/gf. + +package gredis + +func defaultOption() *Option { + return &Option{} +} + +func parseArgsToArgsAndOption(arguments []interface{}) (args []interface{}, option *Option) { + if length := len(arguments); length > 0 { + lastElement := arguments[length-1] + switch result := lastElement.(type) { + case Option: + return arguments[:length-1], &result + + case *Option: + return arguments[:length-1], result + } + } + return arguments, defaultOption() +} diff --git a/database/gredis/gredis_z_unit_conn_test.go b/database/gredis/gredis_z_unit_conn_test.go index 00e1619f2..c4d3fd72e 100644 --- a/database/gredis/gredis_z_unit_conn_test.go +++ b/database/gredis/gredis_z_unit_conn_test.go @@ -22,37 +22,42 @@ func TestConn_DoWithTimeout(t *testing.T) { gtest.C(t, func(t *gtest.T) { redis, err := gredis.New(config) t.AssertNil(err) - t.AssertNil(redis) + t.AssertNE(redis, nil) + defer redis.Close(ctx) conn, err := redis.Conn(ctx) t.AssertNil(err) defer conn.Close(ctx) - _, err := conn.Do(ctx, "set", "test", "123", &gredis.Option{ReadTimeout: time.Second}) + _, err = conn.Do(ctx, "set", "test", "123", &gredis.Option{ReadTimeout: time.Second}) t.Assert(err, nil) - defer conn.DoWithTimeout(time.Second, "del", "test") + defer conn.Do(ctx, "del", "test") - r, err := conn.DoWithTimeout(time.Second, "get", "test") + r, err := conn.Do(ctx, "get", "test", &gredis.Option{ReadTimeout: time.Second}) t.Assert(err, nil) - t.Assert(r, "123") + t.Assert(r.String(), "123") }) } func TestConn_ReceiveVarWithTimeout(t *testing.T) { gtest.C(t, func(t *gtest.T) { - redis := gredis.New(config) + redis, err := gredis.New(config) + t.AssertNil(err) t.AssertNE(redis, nil) - conn := redis.Conn() - defer conn.Close() + defer redis.Close(ctx) - _, err := conn.DoVarWithTimeout(time.Second, "Subscribe", "gf") - t.Assert(err, nil) + conn, err := redis.Conn(ctx) + t.AssertNil(err) + defer conn.Close(ctx) - v, err := redis.DoVarWithTimeout(time.Second, "PUBLISH", "gf", "test") + _, err = conn.Do(ctx, "Subscribe", "gf", &gredis.Option{ReadTimeout: time.Second}) + t.AssertNil(err) + + v, err := redis.Do(ctx, "PUBLISH", "gf", "test", &gredis.Option{ReadTimeout: time.Second}) t.Assert(err, nil) t.Assert(v.String(), "1") - v, _ = conn.ReceiveVar() + v, _ = conn.Receive(ctx) t.Assert(len(v.Strings()), 3) t.Assert(v.Strings()[2], "test") }) diff --git a/database/gredis/gredis_z_unit_test.go b/database/gredis/gredis_z_unit_test.go index bf24e991f..e6b124043 100644 --- a/database/gredis/gredis_z_unit_test.go +++ b/database/gredis/gredis_z_unit_test.go @@ -31,27 +31,32 @@ var ( func Test_NewClose(t *testing.T) { gtest.C(t, func(t *gtest.T) { - redis := gredis.New(config) + redis, err := gredis.New(config) + t.AssertNil(err) t.AssertNE(redis, nil) - err := redis.Close() - t.Assert(err, nil) + + err = redis.Close(ctx) + t.AssertNil(err) }) } func Test_Do(t *testing.T) { gtest.C(t, func(t *gtest.T) { - redis := gredis.New(config) - defer redis.Close() - _, err := redis.Do("SET", "k", "v") + redis, err := gredis.New(config) + t.AssertNil(err) + t.AssertNE(redis, nil) + defer redis.Close(ctx) + + _, err = redis.Do(ctx, "SET", "k", "v") t.Assert(err, nil) - r, err := redis.Do("GET", "k") + r, err := redis.Do(ctx, "GET", "k") t.Assert(err, nil) t.Assert(r, []byte("v")) - _, err = redis.Do("DEL", "k") + _, err = redis.Do(ctx, "DEL", "k") t.Assert(err, nil) - r, err = redis.Do("GET", "k") + r, err = redis.Do(ctx, "GET", "k") t.Assert(err, nil) t.Assert(r, nil) }) @@ -59,26 +64,30 @@ func Test_Do(t *testing.T) { func Test_Stats(t *testing.T) { gtest.C(t, func(t *gtest.T) { - redis := gredis.New(config) - defer redis.Close() - redis.SetMaxIdle(2) - redis.SetMaxActive(100) - redis.SetIdleTimeout(500 * time.Millisecond) - redis.SetMaxConnLifetime(500 * time.Millisecond) + redis, err := gredis.New(config) + t.AssertNil(err) + t.AssertNE(redis, nil) + defer redis.Close(ctx) - array := make([]*gredis.Conn, 0) + array := make([]*gredis.RedisConn, 0) for i := 0; i < 10; i++ { - array = append(array, redis.Conn()) + conn, err := redis.Conn(ctx) + t.AssertNil(err) + array = append(array, conn) } - stats := redis.Stats() - t.Assert(stats.ActiveCount, 10) - t.Assert(stats.IdleCount, 0) + stats, err := redis.Stats(ctx) + t.AssertNil(err) + t.Assert(stats.ActiveCount(), 10) + t.Assert(stats.IdleCount(), 0) + for i := 0; i < 10; i++ { - array[i].Close() + t.AssertNil(array[i].Close(ctx)) } - stats = redis.Stats() - t.Assert(stats.ActiveCount, 2) - t.Assert(stats.IdleCount, 2) + + stats, err = redis.Stats(ctx) + t.AssertNil(err) + t.Assert(stats.ActiveCount(), 10) + t.Assert(stats.IdleCount(), 10) //time.Sleep(3000*time.Millisecond) //stats = redis.Stats() //fmt.Println(stats) @@ -89,23 +98,27 @@ func Test_Stats(t *testing.T) { func Test_Conn(t *testing.T) { gtest.C(t, func(t *gtest.T) { - redis := gredis.New(config) - defer redis.Close() - conn := redis.Conn() - defer conn.Close() + redis, err := gredis.New(config) + t.AssertNil(err) + t.AssertNE(redis, nil) + defer redis.Close(ctx) + + conn, err := redis.Conn(ctx) + t.AssertNil(err) + defer conn.Close(ctx) key := gconv.String(gtime.TimestampNano()) value := []byte("v") - r, err := conn.Do("SET", key, value) + r, err := conn.Do(ctx, "SET", key, value) t.Assert(err, nil) - r, err = conn.Do("GET", key) + r, err = conn.Do(ctx, "GET", key) t.Assert(err, nil) t.Assert(r, value) - _, err = conn.Do("DEL", key) + _, err = conn.Do(ctx, "DEL", key) t.Assert(err, nil) - r, err = conn.Do("GET", key) + r, err = conn.Do(ctx, "GET", key) t.Assert(err, nil) t.Assert(r, nil) }) @@ -116,22 +129,24 @@ func Test_Instance(t *testing.T) { group := "my-test" gredis.SetConfig(config, group) defer gredis.RemoveConfig(group) + redis := gredis.Instance(group) - defer redis.Close() + defer redis.Close(ctx) - conn := redis.Conn() - defer conn.Close() + conn, err := redis.Conn(ctx) + t.AssertNil(err) + defer conn.Close(ctx) - _, err := conn.Do("SET", "k", "v") + _, err = conn.Do(ctx, "SET", "k", "v") t.Assert(err, nil) - r, err := conn.Do("GET", "k") + r, err := conn.Do(ctx, "GET", "k") t.Assert(err, nil) t.Assert(r, []byte("v")) - _, err = conn.Do("DEL", "k") + _, err = conn.Do(ctx, "DEL", "k") t.Assert(err, nil) - r, err = conn.Do("GET", "k") + r, err = conn.Do(ctx, "GET", "k") t.Assert(err, nil) t.Assert(r, nil) }) @@ -145,8 +160,12 @@ func Test_Error(t *testing.T) { Db: 1, ConnectTimeout: time.Second, } - redis := gredis.New(config1) - _, err := redis.Do("info") + redis, err := gredis.New(config1) + t.AssertNil(err) + t.AssertNE(redis, nil) + defer redis.Close(ctx) + + _, err = redis.Do(ctx, "info") t.AssertNE(err, nil) config1 = &gredis.Config{ @@ -154,35 +173,43 @@ func Test_Error(t *testing.T) { Port: 6379, Db: 100, } - redis = gredis.New(config1) - _, err = redis.Do("info") + redis, err = gredis.New(config1) + t.AssertNil(err) + t.AssertNE(redis, nil) + defer redis.Close(ctx) + + _, err = redis.Do(ctx, "info") t.AssertNE(err, nil) redis = gredis.Instance("gf") t.Assert(redis == nil, true) gredis.ClearConfig() - redis = gredis.New(config) - defer redis.Close() - _, err = redis.DoVar("SET", "k", "v") + redis, err = gredis.New(config) + t.AssertNil(err) + t.AssertNE(redis, nil) + defer redis.Close(ctx) + + _, err = redis.Do(ctx, "SET", "k", "v") t.Assert(err, nil) - v, err := redis.DoVar("GET", "k") + v, err := redis.Do(ctx, "GET", "k") t.Assert(err, nil) t.Assert(v.String(), "v") - conn := redis.Conn() - defer conn.Close() - _, err = conn.DoVar("SET", "k", "v") + conn, err := redis.Conn(ctx) + t.AssertNil(err) + defer conn.Close(ctx) + _, err = conn.Do(ctx, "SET", "k", "v") t.Assert(err, nil) - _, err = conn.DoVar("Subscribe", "gf") + _, err = conn.Do(ctx, "Subscribe", "gf") t.Assert(err, nil) - _, err = redis.DoVar("PUBLISH", "gf", "test") + _, err = redis.Do(ctx, "PUBLISH", "gf", "test") t.Assert(err, nil) - v, _ = conn.ReceiveVar() + v, _ = conn.Receive(ctx) t.Assert(len(v.Strings()), 3) t.Assert(v.Strings()[2], "test") @@ -192,23 +219,27 @@ func Test_Error(t *testing.T) { func Test_Bool(t *testing.T) { gtest.C(t, func(t *gtest.T) { - redis := gredis.New(config) + redis, err := gredis.New(config) + t.AssertNil(err) + t.AssertNE(redis, nil) + defer redis.Close(ctx) + defer func() { - redis.Do("DEL", "key-true") - redis.Do("DEL", "key-false") + redis.Do(ctx, "DEL", "key-true") + redis.Do(ctx, "DEL", "key-false") }() - _, err := redis.Do("SET", "key-true", true) + _, err = redis.Do(ctx, "SET", "key-true", true) t.Assert(err, nil) - _, err = redis.Do("SET", "key-false", false) + _, err = redis.Do(ctx, "SET", "key-false", false) t.Assert(err, nil) - r, err := redis.DoVar("GET", "key-true") + r, err := redis.Do(ctx, "GET", "key-true") t.Assert(err, nil) t.Assert(r.Bool(), true) - r, err = redis.DoVar("GET", "key-false") + r, err = redis.Do(ctx, "GET", "key-false") t.Assert(err, nil) t.Assert(r.Bool(), false) }) @@ -216,14 +247,18 @@ func Test_Bool(t *testing.T) { func Test_Int(t *testing.T) { gtest.C(t, func(t *gtest.T) { - redis := gredis.New(config) - key := guid.S() - defer redis.Do("DEL", key) + redis, err := gredis.New(config) + t.AssertNil(err) + t.AssertNE(redis, nil) + defer redis.Close(ctx) - _, err := redis.Do("SET", key, 1) + key := guid.S() + defer redis.Do(ctx, "DEL", key) + + _, err = redis.Do(ctx, "SET", key, 1) t.Assert(err, nil) - r, err := redis.DoVar("GET", key) + r, err := redis.Do(ctx, "GET", key) t.Assert(err, nil) t.Assert(r.Int(), 1) }) @@ -231,14 +266,18 @@ func Test_Int(t *testing.T) { func Test_HSet(t *testing.T) { gtest.C(t, func(t *gtest.T) { - redis := gredis.New(config) - key := guid.S() - defer redis.Do("DEL", key) + redis, err := gredis.New(config) + t.AssertNil(err) + t.AssertNE(redis, nil) + defer redis.Close(ctx) - _, err := redis.Do("HSET", key, "name", "john") + key := guid.S() + defer redis.Do(ctx, "DEL", key) + + _, err = redis.Do(ctx, "HSET", key, "name", "john") t.Assert(err, nil) - r, err := redis.DoVar("HGETALL", key) + r, err := redis.Do(ctx, "HGETALL", key) t.Assert(err, nil) t.Assert(r.Strings(), g.ArrayStr{"name", "john"}) }) @@ -247,18 +286,20 @@ func Test_HSet(t *testing.T) { func Test_HGetAll1(t *testing.T) { gtest.C(t, func(t *gtest.T) { var ( - err error - key = guid.S() - redis = gredis.New(config) + key = guid.S() ) - defer redis.Do("DEL", key) + redis, err := gredis.New(config) + t.AssertNil(err) + t.AssertNE(redis, nil) + defer redis.Close(ctx) + defer redis.Do(ctx, "DEL", key) - _, err = redis.Do("HSET", key, "id", 100) + _, err = redis.Do(ctx, "HSET", key, "id", 100) t.Assert(err, nil) - _, err = redis.Do("HSET", key, "name", "john") + _, err = redis.Do(ctx, "HSET", key, "name", "john") t.Assert(err, nil) - r, err := redis.DoVar("HGETALL", key) + r, err := redis.Do(ctx, "HGETALL", key) t.Assert(err, nil) t.Assert(r.Map(), g.MapStrAny{ "id": 100, @@ -270,18 +311,20 @@ func Test_HGetAll1(t *testing.T) { func Test_HGetAll2(t *testing.T) { gtest.C(t, func(t *gtest.T) { var ( - err error - key = guid.S() - redis = gredis.New(config) + key = guid.S() ) - defer redis.Do("DEL", key) + redis, err := gredis.New(config) + t.AssertNil(err) + t.AssertNE(redis, nil) + defer redis.Close(ctx) + defer redis.Do(ctx, "DEL", key) - _, err = redis.Do("HSET", key, "id", 100) + _, err = redis.Do(ctx, "HSET", key, "id", 100) t.Assert(err, nil) - _, err = redis.Do("HSET", key, "name", "john") + _, err = redis.Do(ctx, "HSET", key, "name", "john") t.Assert(err, nil) - result, err := redis.DoVar("HGETALL", key) + result, err := redis.Do(ctx, "HGETALL", key) t.Assert(err, nil) t.Assert(gconv.Uint(result.MapStrVar()["id"]), 100) @@ -293,20 +336,22 @@ func Test_HMSet(t *testing.T) { // map gtest.C(t, func(t *gtest.T) { var ( - err error - key = guid.S() - redis = gredis.New(config) - data = g.Map{ + key = guid.S() + data = g.Map{ "name": "gf", "sex": 0, "score": 100, } ) - defer redis.Do("DEL", key) + redis, err := gredis.New(config) + t.AssertNil(err) + t.AssertNE(redis, nil) + defer redis.Close(ctx) + defer redis.Do(ctx, "DEL", key) - _, err = redis.Do("HMSET", append(g.Slice{key}, gutil.MapToSlice(data)...)...) + _, err = redis.Do(ctx, "HMSET", append(g.Slice{key}, gutil.MapToSlice(data)...)...) t.Assert(err, nil) - v, err := redis.DoVar("HMGET", key, "name") + v, err := redis.Do(ctx, "HMGET", key, "name") t.Assert(err, nil) t.Assert(v.Slice(), g.Slice{data["name"]}) }) @@ -318,48 +363,53 @@ func Test_HMSet(t *testing.T) { Score int `json:"score"` } var ( - err error - key = guid.S() - redis = gredis.New(config) - data = &User{ + key = guid.S() + data = &User{ Name: "gf", Sex: 0, Score: 100, } ) - defer redis.Do("DEL", key) + redis, err := gredis.New(config) + t.AssertNil(err) + t.AssertNE(redis, nil) + defer redis.Close(ctx) + defer redis.Do(ctx, "DEL", key) - _, err = redis.Do("HMSET", append(g.Slice{key}, gutil.StructToSlice(data)...)...) + _, err = redis.Do(ctx, "HMSET", append(g.Slice{key}, gutil.StructToSlice(data)...)...) t.Assert(err, nil) - v, err := redis.DoVar("HMGET", key, "name") + v, err := redis.Do(ctx, "HMGET", key, "name") t.Assert(err, nil) t.Assert(v.Slice(), g.Slice{data.Name}) }) } func Test_Auto_Marshal(t *testing.T) { - var ( - err error - redis = gredis.New(config) - key = guid.S() - ) - defer redis.Do("DEL", key) - - type User struct { - Id int - Name string - } - gtest.C(t, func(t *gtest.T) { + var ( + key = guid.S() + ) + redis, err := gredis.New(config) + t.AssertNil(err) + t.AssertNE(redis, nil) + defer redis.Close(ctx) + + defer redis.Do(ctx, "DEL", key) + + type User struct { + Id int + Name string + } + user := &User{ Id: 10000, Name: "john", } - _, err = redis.Do("SET", key, user) + _, err = redis.Do(ctx, "SET", key, user) t.Assert(err, nil) - r, err := redis.DoVar("GET", key) + r, err := redis.Do(ctx, "GET", key) t.Assert(err, nil) t.Assert(r.Map(), g.MapStrAny{ "Id": user.Id, @@ -374,22 +424,20 @@ func Test_Auto_Marshal(t *testing.T) { } func Test_Auto_MarshalSlice(t *testing.T) { - var ( - err error - redis = gredis.New(config) - key = guid.S() - ) - defer redis.Do("DEL", key) - - type User struct { - Id int - Name string - } - gtest.C(t, func(t *gtest.T) { + var ( + key = "user-slice" + ) + redis, err := gredis.New(config) + t.AssertNil(err) + t.AssertNE(redis, nil) + defer redis.Do(ctx, "DEL", key) + type User struct { + Id int + Name string + } var ( result *gvar.Var - key = "user-slice" users1 = []User{ { Id: 1, @@ -402,10 +450,10 @@ func Test_Auto_MarshalSlice(t *testing.T) { } ) - _, err = redis.Do("SET", key, users1) + _, err = redis.Do(ctx, "SET", key, users1) t.Assert(err, nil) - result, err = redis.DoVar("GET", key) + result, err = redis.Do(ctx, "GET", key) t.Assert(err, nil) var users2 []User diff --git a/os/gsession/gsession_session.go b/os/gsession/gsession_session.go index dc79606f4..6a954d6bf 100644 --- a/os/gsession/gsession_session.go +++ b/os/gsession/gsession_session.go @@ -239,7 +239,7 @@ func (s *Session) Size() int { // Contains checks whether key exist in the session. func (s *Session) Contains(key string) bool { s.init() - return s.Get(key) != nil + return !s.Get(key).IsNil() } // IsDirty checks whether there's any data changes in the session. diff --git a/os/gsession/gsession_storage_redis_hashtable.go b/os/gsession/gsession_storage_redis_hashtable.go index 71e4d2eee..ac11a3591 100644 --- a/os/gsession/gsession_storage_redis_hashtable.go +++ b/os/gsession/gsession_storage_redis_hashtable.go @@ -46,21 +46,24 @@ func (s *StorageRedisHashTable) New(ctx context.Context, ttl time.Duration) (id // Get retrieves session value with given key. // It returns nil if the key does not exist in the session. func (s *StorageRedisHashTable) Get(ctx context.Context, id string, key string) (value interface{}, err error) { - value, err = s.redis.Do(ctx, "HGET", s.key(id), key) - if value != nil { - value = gconv.String(value) + v, err := s.redis.Do(ctx, "HGET", s.key(id), key) + if err != nil { + return nil, err } - return + if v.IsNil() { + return nil, nil + } + return v.String(), nil } // GetMap retrieves all key-value pairs as map from storage. func (s *StorageRedisHashTable) GetMap(ctx context.Context, id string) (data map[string]interface{}, err error) { - r, err := s.redis.Do(ctx, "HGETALL", s.key(id)) + v, err := s.redis.Do(ctx, "HGETALL", s.key(id)) if err != nil { return nil, err } data = make(map[string]interface{}) - array := r.Interfaces() + array := v.Interfaces() for i := 0; i < len(array); i += 2 { if array[i+1] != nil { data[gconv.String(array[i])] = gconv.String(array[i+1]) diff --git a/os/gsession/gsession_unit_storage_redis_hashtable_test.go b/os/gsession/gsession_unit_storage_redis_hashtable_test.go index 20d7ff082..ce3f0527a 100644 --- a/os/gsession/gsession_unit_storage_redis_hashtable_test.go +++ b/os/gsession/gsession_unit_storage_redis_hashtable_test.go @@ -18,9 +18,10 @@ import ( ) func Test_StorageRedisHashTable(t *testing.T) { - redis, err := gredis.NewFromStr("127.0.0.1:6379,0") + config, _ := gredis.ConfigFromStr("127.0.0.1:6379,0") + redis, err := gredis.New(config) gtest.C(t, func(t *gtest.T) { - t.Assert(err, nil) + t.AssertNil(err) }) storage := gsession.NewStorageRedisHashTable(redis) @@ -80,7 +81,8 @@ func Test_StorageRedisHashTable(t *testing.T) { } func Test_StorageRedisHashTablePrefix(t *testing.T) { - redis, err := gredis.NewFromStr("127.0.0.1:6379,0") + config, _ := gredis.ConfigFromStr("127.0.0.1:6379,0") + redis, err := gredis.New(config) gtest.C(t, func(t *gtest.T) { t.Assert(err, nil) }) diff --git a/os/gsession/gsession_unit_storage_redis_test.go b/os/gsession/gsession_unit_storage_redis_test.go index 53a5e754b..4b9b74ef8 100644 --- a/os/gsession/gsession_unit_storage_redis_test.go +++ b/os/gsession/gsession_unit_storage_redis_test.go @@ -18,7 +18,8 @@ import ( ) func Test_StorageRedis(t *testing.T) { - redis, err := gredis.NewFromStr("127.0.0.1:6379,0") + config, _ := gredis.ConfigFromStr("127.0.0.1:6379,0") + redis, err := gredis.New(config) gtest.Assert(err, nil) storage := gsession.NewStorageRedis(redis) @@ -79,7 +80,8 @@ func Test_StorageRedis(t *testing.T) { } func Test_StorageRedisPrefix(t *testing.T) { - redis, err := gredis.NewFromStr("127.0.0.1:6379,0") + config, _ := gredis.ConfigFromStr("127.0.0.1:6379,0") + redis, err := gredis.New(config) gtest.Assert(err, nil) prefix := "s_"