Change API and update tests.

This commit is contained in:
Vladimir Mihailenco 2012-08-06 15:09:48 +03:00
parent c5c8ec6b0c
commit 05223145e0
6 changed files with 1184 additions and 965 deletions

View File

@ -33,14 +33,14 @@ Example 2:
}
initConn := func(client *redis.Client) error {
_, err := client.Auth("foo").Reply()
if err != nil {
return err
auth := client.Auth("foo")
if auth.Err() != nil {
return auth.Err()
}
_, err = client.Ping().Reply()
if err != nil {
return err
ping := client.Ping()
if ping.Err() != nil {
return ping.Err()
}
return nil
@ -53,17 +53,19 @@ Both `closeConn` and `initConn` functions can be `nil`.
Running commands
----------------
_, err := redisClient.Set("foo", "bar").Reply()
if err != nil {
panic(err)
set := redisClient.Set("foo", "bar")
if set.Err() != nil {
panic(set.Err())
}
ok := set.Val()
value, err := redisClient.Get("foo").Reply()
if err != nil {
if err != redis.Nil {
panic(err)
get := redisClient.Get("foo")
if get.Err() != nil {
if get.Err() != redis.Nil {
panic(get.Err())
}
}
val := get.Val()
Pipelining
----------
@ -80,16 +82,12 @@ Client has ability to run several commands with one read/write:
panic(err)
}
ok, err := setReq.Reply()
if err != nil {
panic(err)
if setReq.Err() != nil {
panic(setReq.Err())
}
value, err := getReq.Reply()
if err != nil {
if err != redis.Nil {
panic(err)
}
if getReq.Err() != nil && getReq.Err() != redis.Nil {
panic(getReq.Err())
}
Multi/Exec
@ -99,26 +97,22 @@ Example 1:
multiClient := redisClient.Multi()
futureGet1 := multiClient.Get("foo1")
futureGet2 := multiClient.Get("foo2")
get1 := multiClient.Get("foo1")
get2 := multiClient.Get("foo2")
_, err := multiClient.Exec()
if err != nil {
panic(err)
}
value1, err := futureGet1.Reply()
if err != nil {
if err != redis.Nil {
panic(err)
}
if get1.Err() != nil && get1.Err() != redis.Nil {
panic(get1.Err())
}
val1 := get1.Val()
value2, err := futureGet2.Reply()
if err != nil {
if err != redis.Nil {
panic(err)
}
if get2.Err() != nil && get2.Err() != redis.Nil {
panic(get2.Err())
}
val2 := get2.Val()
Example 2:
@ -132,11 +126,8 @@ Example 2:
}
for req := range reqs {
value, err := req.Reply()
if err != nil {
if err != redis.Nil {
panic(err)
}
if req.Err() != nil && req.Err() != redis.Nil {
panic(req.Err())
}
}
@ -145,14 +136,17 @@ Pub/sub
Publish:
_, err := redisClient.Publish("mychannel", "hello").Reply()
if err != nil {
panic(err)
pub := redisClient.Publish("mychannel", "hello")
if pub.Err() != nil {
panic(pub.Err())
}
Subscribe:
pubsub := redisClient.PubSubClient()
pubsub, err := redisClient.PubSubClient()
if err != nil {
panic(err)
}
ch, err := pubsub.Subscribe("mychannel")
if err != nil {
@ -164,18 +158,18 @@ Subscribe:
if msg.Err != nil {
panic(err)
}
fmt.Println(msg.Message)
message := msg.Message
}
}
Thread safety
-------------
redis.Client methods are thread safe. Following code is correct:
Commands are thread safe. Following code is correct:
for i := 0; i < 1000; i++ {
go func() {
redisClient.Incr("foo").Reply()
redisClient.Incr("foo")
}()
}
@ -186,15 +180,13 @@ Example:
func Get(client *redis.Client, key string) *redis.BulkReq {
req := redis.NewBulkReq("GET", key)
client.Queue(req)
client.Process(req)
return req
}
value, err := Get(redisClient, "foo").Reply()
if err != nil {
if err != redis.Nil {
panic(err)
}
get := Get(redisClient, "foo")
if get.Err() != nil && get.Err() != redis.Nil {
panic(get.Err())
}
Connection pool

View File

@ -326,7 +326,7 @@ func (c *Client) SetEx(key string, seconds int64, value string) *StatusReq {
return req
}
func (c *Client) SetNx(key, value string) *BoolReq {
func (c *Client) SetNX(key, value string) *BoolReq {
req := NewBoolReq("SETNX", key, value)
c.Process(req)
return req
@ -679,8 +679,8 @@ func (c *Client) ZCount(key, min, max string) *IntReq {
return req
}
func (c *Client) ZIncrBy(key string, increment int64, member string) *IntReq {
req := NewIntReq("ZINCRBY", key, strconv.FormatInt(increment, 10), member)
func (c *Client) ZIncrBy(key string, increment int64, member string) *FloatReq {
req := NewFloatReq("ZINCRBY", key, strconv.FormatInt(increment, 10), member)
c.Process(req)
return req
}

View File

@ -6,7 +6,6 @@ import (
"io"
"net"
"sync"
"time"
"github.com/vmihailenco/bufreader"
)
@ -34,16 +33,16 @@ func AuthSelectFunc(password string, db int64) InitConnFunc {
return func(client *Client) error {
if password != "" {
_, err := client.Auth(password).Reply()
if err != nil {
return err
auth := client.Auth(password)
if auth.Err() != nil {
return auth.Err()
}
}
if db >= 0 {
_, err := client.Select(db).Reply()
if err != nil {
return err
sel := client.Select(db)
if sel.Err() != nil {
return sel.Err()
}
}
@ -105,13 +104,6 @@ func (c *Client) WriteReq(buf []byte, conn *Conn) error {
}
func (c *Client) ReadReply(conn *Conn) error {
if false {
err := conn.RW.(*net.TCPConn).SetReadDeadline(time.Now().Add(time.Second))
if err != nil {
return err
}
}
_, err := conn.Rd.ReadFrom(conn.RW)
if err != nil {
return err
@ -120,8 +112,6 @@ func (c *Client) ReadReply(conn *Conn) error {
}
func (c *Client) WriteRead(buf []byte, conn *Conn) error {
c.mtx.Lock()
defer c.mtx.Unlock()
if err := c.WriteReq(buf, conn); err != nil {
return err
}

File diff suppressed because it is too large Load Diff

View File

@ -82,7 +82,7 @@ type Req interface {
SetErr(error)
Err() error
SetVal(interface{})
Val() interface{}
InterfaceVal() interface{}
}
//------------------------------------------------------------------------------
@ -112,7 +112,13 @@ func (r *BaseReq) SetErr(err error) {
}
func (r *BaseReq) Err() error {
if r.err != nil {
return r.err
}
if r.val == nil {
return errResultMissing
}
return nil
}
func (r *BaseReq) SetVal(val interface{}) {
@ -122,7 +128,7 @@ func (r *BaseReq) SetVal(val interface{}) {
r.val = val
}
func (r *BaseReq) Val() interface{} {
func (r *BaseReq) InterfaceVal() interface{} {
return r.val
}
@ -157,13 +163,11 @@ func (r *StatusReq) ParseReply(rd *bufreader.Reader) (interface{}, error) {
return string(line[1:]), nil
}
func (r *StatusReq) Reply() (string, error) {
if r.val == nil && r.err == nil {
return "", errResultMissing
} else if r.err != nil {
return "", r.err
func (r *StatusReq) Val() string {
if r.val == nil {
return ""
}
return r.val.(string), nil
return r.val.(string)
}
//------------------------------------------------------------------------------
@ -193,13 +197,11 @@ func (r *IntReq) ParseReply(rd *bufreader.Reader) (interface{}, error) {
return strconv.ParseInt(string(line[1:]), 10, 64)
}
func (r *IntReq) Reply() (int64, error) {
if r.val == nil && r.err == nil {
return 0, errResultMissing
} else if r.err != nil {
return 0, r.err
func (r *IntReq) Val() int64 {
if r.val == nil {
return 0
}
return r.val.(int64), nil
return r.val.(int64)
}
//------------------------------------------------------------------------------
@ -231,13 +233,11 @@ func (r *IntNilReq) ParseReply(rd *bufreader.Reader) (interface{}, error) {
return nil, fmt.Errorf("Expected ':', but got %q of %q.", line, rd.Bytes())
}
func (r *IntNilReq) Reply() (int64, error) {
if r.val == nil && r.err == nil {
return 0, errResultMissing
} else if r.err != nil {
return 0, r.err
func (r *IntNilReq) Val() int64 {
if r.val == nil {
return 0
}
return r.val.(int64), nil
return r.val.(int64)
}
//------------------------------------------------------------------------------
@ -267,13 +267,11 @@ func (r *BoolReq) ParseReply(rd *bufreader.Reader) (interface{}, error) {
return line[1] == '1', nil
}
func (r *BoolReq) Reply() (bool, error) {
if r.val == nil && r.err == nil {
return false, errResultMissing
} else if r.err != nil {
return false, r.err
func (r *BoolReq) Val() bool {
if r.val == nil {
return false
}
return r.val.(bool), nil
return r.val.(bool)
}
//------------------------------------------------------------------------------
@ -312,13 +310,11 @@ func (r *BulkReq) ParseReply(rd *bufreader.Reader) (interface{}, error) {
return string(line), nil
}
func (r *BulkReq) Reply() (string, error) {
if r.val == nil && r.err == nil {
return "", errResultMissing
} else if r.err != nil {
return "", r.err
func (r *BulkReq) Val() string {
if r.val == nil {
return ""
}
return r.val.(string), nil
return r.val.(string)
}
//------------------------------------------------------------------------------
@ -357,13 +353,11 @@ func (r *FloatReq) ParseReply(rd *bufreader.Reader) (interface{}, error) {
return strconv.ParseFloat(string(line), 64)
}
func (r *FloatReq) Reply() (float64, error) {
if r.val == nil && r.err == nil {
return 0, errResultMissing
} else if r.err != nil {
return 0, r.err
func (r *FloatReq) Val() float64 {
if r.val == nil {
return 0
}
return r.val.(float64), nil
return r.val.(float64)
}
//------------------------------------------------------------------------------
@ -434,11 +428,9 @@ func (r *MultiBulkReq) ParseReply(rd *bufreader.Reader) (interface{}, error) {
return val, nil
}
func (r *MultiBulkReq) Reply() ([]interface{}, error) {
if r.val == nil && r.err == nil {
return nil, errResultMissing
} else if r.err != nil {
return nil, r.err
func (r *MultiBulkReq) Val() []interface{} {
if r.val == nil {
return nil
}
return r.val.([]interface{}), nil
return r.val.([]interface{})
}

View File

@ -35,9 +35,8 @@ func (t *RequestTest) BenchmarkStatusReq(c *C) {
c.Check(vI, Equals, "OK")
req.SetVal(vI)
v, err := req.Reply()
c.Check(err, IsNil)
c.Check(v, Equals, "OK")
c.Check(req.Err(), IsNil)
c.Check(req.Val(), Equals, "OK")
}
c.StartTimer()
@ -46,6 +45,7 @@ func (t *RequestTest) BenchmarkStatusReq(c *C) {
rd.ResetPos()
v, _ := req.ParseReply(rd)
req.SetVal(v)
req.Reply()
req.Err()
req.Val()
}
}