From a57bd8594664ba487f02cc12c46a1e222bca62a0 Mon Sep 17 00:00:00 2001 From: Brian McQueen Date: Sat, 17 Jan 2015 18:56:49 -0800 Subject: [PATCH 01/14] more tests and some new print lines --- test.go | 32 ++++++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/test.go b/test.go index 2a33334..75cab34 100644 --- a/test.go +++ b/test.go @@ -22,14 +22,18 @@ func main() { keys = append(keys, "c"); keys = append(keys, "d"); val, err = db.Do("multi_get", "a", "b", keys); - fmt.Printf("%s\n", val); + fmt.Printf(":%s:\n", val); + if err != nil { + os.Exit(1) + } db.Set("a", "xxx") val, err = db.Get("a") - fmt.Printf("%s\n", val) - db.Del("a") + fmt.Printf("Got:%v:\n", val) + _, err = db.Del("a") + fmt.Printf("deleted it:err:%v:\n", err) val, err = db.Get("a") - fmt.Printf("%s\n", val) + fmt.Printf("got it again:val:%v:err:%v:\n", val, err) fmt.Printf("----\n"); @@ -48,5 +52,25 @@ func main() { for i := 1; i < len(resp); i += 2 { fmt.Printf(" %s : %3s\n", resp[i], resp[i+1]) } + + fmt.Printf("call:init pool\n") + cpm, err := ssdb.InitPool(ip, port, 11) + fmt.Printf("done call:init pool\n") + + if err != nil { + fmt.Printf("failed to init pool:%v:", err) + os.Exit(1) + } + + // cpm.Put + fmt.Printf("cpm.Set:a:xxx\n") + cpm.Set("a", "xxx") + + fmt.Printf("cpm.Get:a:\n") + val, err = cpm.Get("a") + fmt.Printf("cpm.Get:return:val:%s:err:%v:\n", val, err) + + cpm.Close() + return } From b9d16721696af9c9b357626265c33d7bb0c18629 Mon Sep 17 00:00:00 2001 From: Brian McQueen Date: Sat, 17 Jan 2015 18:57:25 -0800 Subject: [PATCH 02/14] add connection pooling --- ssdb/ssdb.go | 79 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 78 insertions(+), 1 deletion(-) diff --git a/ssdb/ssdb.go b/ssdb/ssdb.go index b4acd2a..00a3d88 100644 --- a/ssdb/ssdb.go +++ b/ssdb/ssdb.go @@ -12,6 +12,39 @@ type Client struct { recv_buf bytes.Buffer } +type ConnectionPoolWrapper struct { + size int + conn chan *Client +} + +func InitPool(ip string, port int, size int) (*ConnectionPoolWrapper, error) { + + cpm := new(ConnectionPoolWrapper) + + // cpm = &ConnectionPoolWrapper{} + cpm.conn = make(chan *Client, size) + for x := 0; x < size; x++ { + conn, err := Connect(ip, port) + if err != nil { + return cpm, err + } + + // If the init function succeeded, add the connection to the channel + cpm.conn <- conn + } + cpm.size = size + return cpm, nil + +} + +func (p *ConnectionPoolWrapper) GetConnection() *Client { + return <-p.conn +} + +func (p *ConnectionPoolWrapper) ReleaseConnection(conn *Client) { + p.conn <- conn +} + func Connect(ip string, port int) (*Client, error) { addr, err := net.ResolveTCPAddr("tcp", fmt.Sprintf("%s:%d", ip, port)) if err != nil { @@ -46,6 +79,15 @@ func (c *Client) Set(key string, val string) (interface{}, error) { return nil, fmt.Errorf("bad response") } + +func (c *ConnectionPoolWrapper) Set(key string, val string) (interface{}, error) { + + db := c.GetConnection() + defer c.ReleaseConnection(db) + + return db.Set(key, val) +} + // TODO: Will somebody write addition semantic methods? func (c *Client) Get(key string) (interface{}, error) { resp, err := c.Do("get", key) @@ -61,19 +103,35 @@ func (c *Client) Get(key string) (interface{}, error) { return nil, fmt.Errorf("bad response") } +func (c *ConnectionPoolWrapper) Get(key string) (interface{}, error) { + + db := c.GetConnection() + defer c.ReleaseConnection(db) + + return db.Get(key) +} + func (c *Client) Del(key string) (interface{}, error) { resp, err := c.Do("del", key) if err != nil { return nil, err } - //response looks like this: [ok 1] + //response looks like this: [ok 1] if len(resp) == 2 && resp[0] == "ok" { return true, nil } return nil, fmt.Errorf("bad response:resp:%v:", resp) } +func (c *ConnectionPoolWrapper) Del(key string) (interface{}, error) { + + db := c.GetConnection() + defer c.ReleaseConnection(db) + + return db.Del(key) +} + func (c *Client) send(args []interface{}) error { var buf bytes.Buffer for _, arg := range args { @@ -177,3 +235,22 @@ func (c *Client) parse() []string { func (c *Client) Close() error { return c.sock.Close() } + + +func (cpm *ConnectionPoolWrapper) Close() error { + + for { + + select { + case db := <- cpm.conn: + // fmt.Printf("ConnectionPoolWrapper.Close:closing one\n") + db.Close() + default: + // fmt.Printf("ConnectionPoolWrapper.Close:skipping\n") + return nil + } + + } + + return nil +} From 9db24d06a1065ae7cc8038ace8f10d28de9e262f Mon Sep 17 00:00:00 2001 From: Brian McQueen Date: Sat, 17 Jan 2015 18:58:12 -0800 Subject: [PATCH 03/14] go test file --- ssdb/ssdb_test.go | 158 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 158 insertions(+) create mode 100644 ssdb/ssdb_test.go diff --git a/ssdb/ssdb_test.go b/ssdb/ssdb_test.go new file mode 100644 index 0000000..b63283b --- /dev/null +++ b/ssdb/ssdb_test.go @@ -0,0 +1,158 @@ +package ssdb + +import "testing" + +var ip = "ssdb" +var port = 16379 + +func TestConnect(t *testing.T) { + + db, err := Connect("zup", port) + if err == nil { + t.Error("connect to bad host did not return err") + } + if db != nil { + t.Error("connect to bad host returned non nil db") + } + + db, err = Connect("ssdb", 0) + if err == nil { + t.Error("connect to bad port did not return err") + } + if db != nil { + t.Error("connect to bad port returned non nil db") + } + + db, err = Connect(ip, port) + if err != nil { + t.Error("Failed to connect") + } + defer db.Close() + +} + +func TestInitPool(t *testing.T) { + + cpm, err := InitPool(ip, port, 11) + if err != nil { + t.Error("failed to init pool") + } + if cpm == nil { + t.Error("failed to init pool") + } + +} + +func TestSet(t *testing.T) { + + db, err := Connect(ip, port) + if err != nil { + t.Error("Failed to connect") + } + //defer db.Close() + + val, err := db.Set("a", "xxx") + if val != true { + t.Error("Set val returned false") + } + if err != nil { + t.Error("Set err returned not nil err") + } + + // add negative testts + db.Close() + + val, err = db.Set("a", "xxx") + if val == true { + t.Error("Set val on closed db returned true") + } + if err == nil { + t.Error("Set err on closed db returned not nil err") + } + + +} + +func TestGet(t *testing.T) { + + db, err := Connect(ip, port) + if err != nil { + t.Error("Failed to connect") + } + defer db.Close() + + val, err := db.Set("a", "xxx") + if val != true { + t.Error("Set val returned false") + } + if err != nil { + t.Error("Set err returned not nil err") + } + + val, err = db.Get("a") + if val == nil { + t.Error("Get returned nil") + } + if err != nil { + t.Error("Get returned err") + } + if val != "xxx" { + t.Error("Get did not return a") + } + +} + +func TestDel(t *testing.T) { + + db, err := Connect(ip, port) + if err != nil { + t.Error("Failed to connect") + } + defer db.Close() + + val, err := db.Set("a", "xxx") + if val != true { + t.Error("Set val returned false") + } + if err != nil { + t.Error("Set err returned not nil err") + } + + val, err = db.Get("a") + if val != "xxx" { + t.Error("Get did not return xxx") + } + if val == nil { + t.Error("Get returned nil") + } + if err != nil { + t.Error("Get returned err") + } + + val, err = db.Del("a") + if val != true { + t.Error("Del returned false") + } + if err != nil { + t.Error("Del returned err") + } + + val, err = db.Get("a") + if val == "xxx" { + t.Error("Get returned xxx after Del") + } + if val != nil { + t.Error("Get returned non-nil") + } + if err != nil { + t.Error("Get returned err") + } + + val, err = db.Del("a") + if val != true { + t.Error("Del returned non-nil:%v:", val) + } + if err != nil { + t.Error("Get returned err") + } +} \ No newline at end of file From 4df538c2574cf4900aca21b7ba149be941f19405 Mon Sep 17 00:00:00 2001 From: Brian McQueen Date: Sat, 17 Jan 2015 22:53:40 -0800 Subject: [PATCH 04/14] add wrapper function around Do --- ssdb/ssdb.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ssdb/ssdb.go b/ssdb/ssdb.go index 00a3d88..b17f537 100644 --- a/ssdb/ssdb.go +++ b/ssdb/ssdb.go @@ -60,6 +60,10 @@ func Connect(ip string, port int) (*Client, error) { } func (c *Client) Do(args ...interface{}) ([]string, error) { + return c.do(args...) +} + +func (c *Client) do(args ...interface{}) ([]string, error) { err := c.send(args) if err != nil { return nil, err From 54820ae92ef237d96690927a2740ad9b11139b61 Mon Sep 17 00:00:00 2001 From: Brian McQueen Date: Sat, 17 Jan 2015 23:49:00 -0800 Subject: [PATCH 05/14] works in parallel with one connection --- ssdb/ssdb.go | 78 ++++++++++++++++++++++++++++++++++++++++------- ssdb/ssdb_test.go | 2 +- test.go | 5 +-- 3 files changed, 71 insertions(+), 14 deletions(-) diff --git a/ssdb/ssdb.go b/ssdb/ssdb.go index b17f537..fb2db21 100644 --- a/ssdb/ssdb.go +++ b/ssdb/ssdb.go @@ -8,7 +8,8 @@ import ( ) type Client struct { - sock *net.TCPConn + // sock *net.TCPConn + sock chan *net.TCPConn recv_buf bytes.Buffer } @@ -55,20 +56,35 @@ func Connect(ip string, port int) (*Client, error) { return nil, err } var c Client - c.sock = sock + // c.sock = sock + c.sock = make(chan *net.TCPConn, 1) + // fmt.Printf("Connect:putting socket:\n") + c.sock <- sock + // fmt.Printf("Connect:done putting socket:\n") return &c, nil } func (c *Client) Do(args ...interface{}) ([]string, error) { - return c.do(args...) + + // fmt.Printf("Do:pulling socket\n") + sock := <- c.sock + // fmt.Printf("Do:done pulling socket\n") + defer func () { + // fmt.Printf("Do:putting socket\n") + c.sock <- sock + // fmt.Printf("Do:done putting socket\n") + + }() + + return c.do(sock, args...) } -func (c *Client) do(args ...interface{}) ([]string, error) { - err := c.send(args) +func (c *Client) do(sock *net.TCPConn, args ...interface{}) ([]string, error) { + err := c.send(sock, args) if err != nil { return nil, err } - resp, err := c.recv() + resp, err := c.recv(sock) return resp, err } @@ -136,7 +152,7 @@ func (c *ConnectionPoolWrapper) Del(key string) (interface{}, error) { return db.Del(key) } -func (c *Client) send(args []interface{}) error { +func (c *Client) send(sock *net.TCPConn, args []interface{}) error { var buf bytes.Buffer for _, arg := range args { var s string @@ -176,15 +192,40 @@ func (c *Client) send(args []interface{}) error { buf.WriteByte('\n') } buf.WriteByte('\n') - _, err := c.sock.Write(buf.Bytes()) + + // fmt.Printf("send:pulling socket\n") + // sock := <- c.sock + // fmt.Printf("send:done pulling socket\n") + // defer func () { + // fmt.Printf("send:putting socket\n") + // c.sock <- sock + // fmt.Printf("send:done putting socket\n") + + // }() + + _, err := sock.Write(buf.Bytes()) + return err } -func (c *Client) recv() ([]string, error) { +func (c *Client) recv(sock *net.TCPConn) ([]string, error) { var tmp [8192]byte + + // fmt.Printf("recv:pulling socket\n") + // sock := <- c.sock + // fmt.Printf("recv:done pulling socket\n") + + // defer func () { + // fmt.Printf("recv:putting socket\n") + // c.sock <- sock + // fmt.Printf("recv:done putting socket\n") + + // }() + for { - n, err := c.sock.Read(tmp[0:]) + n, err := sock.Read(tmp[0:]) if err != nil { + return nil, err } c.recv_buf.Write(tmp[0:n]) @@ -237,7 +278,22 @@ func (c *Client) parse() []string { // Close The Client Connection func (c *Client) Close() error { - return c.sock.Close() + + // fmt.Printf("Close:pulling socket\n") + sock := <- c.sock + // fmt.Printf("Close:done pulling socket\n") + // defer func () { c.sock <- sock }() + // fmt.Printf("recv:done pulling socket\n") + + defer func () { + // fmt.Printf("Close:putting socket\n") + c.sock <- sock + // fmt.Printf("Close:done putting socket\n") + + }() + + return sock.Close() + } diff --git a/ssdb/ssdb_test.go b/ssdb/ssdb_test.go index b63283b..532d8b6 100644 --- a/ssdb/ssdb_test.go +++ b/ssdb/ssdb_test.go @@ -31,7 +31,7 @@ func TestConnect(t *testing.T) { } -func TestInitPool(t *testing.T) { +func QTestInitPool(t *testing.T) { cpm, err := InitPool(ip, port, 11) if err != nil { diff --git a/test.go b/test.go index 75cab34..34ac04f 100644 --- a/test.go +++ b/test.go @@ -8,10 +8,11 @@ import ( ) func main() { - ip := "127.0.0.1" - port := 8888 + ip := "ssdb" + port := 16379 db, err := ssdb.Connect(ip, port) if err != nil { + fmt.Errorf("ssdb.Connect:err:%v:\n", err) os.Exit(1) } From 7caa1173700250a5f4b32b4737b1eb4f384ad84b Mon Sep 17 00:00:00 2001 From: Brian McQueen Date: Sun, 18 Jan 2015 00:03:04 -0800 Subject: [PATCH 06/14] restore the api for send and recv --- ssdb/ssdb.go | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/ssdb/ssdb.go b/ssdb/ssdb.go index fb2db21..090ce18 100644 --- a/ssdb/ssdb.go +++ b/ssdb/ssdb.go @@ -8,9 +8,9 @@ import ( ) type Client struct { - // sock *net.TCPConn sock chan *net.TCPConn recv_buf bytes.Buffer + _sock *net.TCPConn } type ConnectionPoolWrapper struct { @@ -22,7 +22,6 @@ func InitPool(ip string, port int, size int) (*ConnectionPoolWrapper, error) { cpm := new(ConnectionPoolWrapper) - // cpm = &ConnectionPoolWrapper{} cpm.conn = make(chan *Client, size) for x := 0; x < size; x++ { conn, err := Connect(ip, port) @@ -56,7 +55,7 @@ func Connect(ip string, port int) (*Client, error) { return nil, err } var c Client - // c.sock = sock + c.sock = make(chan *net.TCPConn, 1) // fmt.Printf("Connect:putting socket:\n") c.sock <- sock @@ -67,24 +66,24 @@ func Connect(ip string, port int) (*Client, error) { func (c *Client) Do(args ...interface{}) ([]string, error) { // fmt.Printf("Do:pulling socket\n") - sock := <- c.sock + c._sock = <- c.sock // fmt.Printf("Do:done pulling socket\n") defer func () { // fmt.Printf("Do:putting socket\n") - c.sock <- sock + c.sock <- c._sock // fmt.Printf("Do:done putting socket\n") }() - return c.do(sock, args...) + return c.do(args...) } -func (c *Client) do(sock *net.TCPConn, args ...interface{}) ([]string, error) { - err := c.send(sock, args) +func (c *Client) do(args ...interface{}) ([]string, error) { + err := c.send(args) if err != nil { return nil, err } - resp, err := c.recv(sock) + resp, err := c.recv() return resp, err } @@ -152,7 +151,9 @@ func (c *ConnectionPoolWrapper) Del(key string) (interface{}, error) { return db.Del(key) } -func (c *Client) send(sock *net.TCPConn, args []interface{}) error { +func (c *Client) send(args []interface{}) error { + + var sock = c._sock var buf bytes.Buffer for _, arg := range args { var s string @@ -208,7 +209,9 @@ func (c *Client) send(sock *net.TCPConn, args []interface{}) error { return err } -func (c *Client) recv(sock *net.TCPConn) ([]string, error) { +func (c *Client) recv() ([]string, error) { + + var sock = c._sock var tmp [8192]byte // fmt.Printf("recv:pulling socket\n") From d0caab3f3b33f62951e724ab30a3ca6e4d9cf95a Mon Sep 17 00:00:00 2001 From: Brian McQueen Date: Sun, 18 Jan 2015 00:07:10 -0800 Subject: [PATCH 07/14] remove ugly commented code --- ssdb/ssdb.go | 38 ++------------------------------------ 1 file changed, 2 insertions(+), 36 deletions(-) diff --git a/ssdb/ssdb.go b/ssdb/ssdb.go index 090ce18..fc4aef3 100644 --- a/ssdb/ssdb.go +++ b/ssdb/ssdb.go @@ -57,22 +57,16 @@ func Connect(ip string, port int) (*Client, error) { var c Client c.sock = make(chan *net.TCPConn, 1) - // fmt.Printf("Connect:putting socket:\n") c.sock <- sock - // fmt.Printf("Connect:done putting socket:\n") + return &c, nil } func (c *Client) Do(args ...interface{}) ([]string, error) { - // fmt.Printf("Do:pulling socket\n") c._sock = <- c.sock - // fmt.Printf("Do:done pulling socket\n") defer func () { - // fmt.Printf("Do:putting socket\n") c.sock <- c._sock - // fmt.Printf("Do:done putting socket\n") - }() return c.do(args...) @@ -194,16 +188,6 @@ func (c *Client) send(args []interface{}) error { } buf.WriteByte('\n') - // fmt.Printf("send:pulling socket\n") - // sock := <- c.sock - // fmt.Printf("send:done pulling socket\n") - // defer func () { - // fmt.Printf("send:putting socket\n") - // c.sock <- sock - // fmt.Printf("send:done putting socket\n") - - // }() - _, err := sock.Write(buf.Bytes()) return err @@ -214,17 +198,6 @@ func (c *Client) recv() ([]string, error) { var sock = c._sock var tmp [8192]byte - // fmt.Printf("recv:pulling socket\n") - // sock := <- c.sock - // fmt.Printf("recv:done pulling socket\n") - - // defer func () { - // fmt.Printf("recv:putting socket\n") - // c.sock <- sock - // fmt.Printf("recv:done putting socket\n") - - // }() - for { n, err := sock.Read(tmp[0:]) if err != nil { @@ -282,16 +255,11 @@ func (c *Client) parse() []string { // Close The Client Connection func (c *Client) Close() error { - // fmt.Printf("Close:pulling socket\n") sock := <- c.sock - // fmt.Printf("Close:done pulling socket\n") - // defer func () { c.sock <- sock }() - // fmt.Printf("recv:done pulling socket\n") defer func () { - // fmt.Printf("Close:putting socket\n") + c.sock <- sock - // fmt.Printf("Close:done putting socket\n") }() @@ -306,10 +274,8 @@ func (cpm *ConnectionPoolWrapper) Close() error { select { case db := <- cpm.conn: - // fmt.Printf("ConnectionPoolWrapper.Close:closing one\n") db.Close() default: - // fmt.Printf("ConnectionPoolWrapper.Close:skipping\n") return nil } From 9a1265901babf13f1d9b4761cca2a91e6b903c81 Mon Sep 17 00:00:00 2001 From: Brian McQueen Date: Sun, 18 Jan 2015 00:11:32 -0800 Subject: [PATCH 08/14] fix merge conflict --- ssdb/ssdb.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ssdb/ssdb.go b/ssdb/ssdb.go index fc4aef3..890a76a 100644 --- a/ssdb/ssdb.go +++ b/ssdb/ssdb.go @@ -86,7 +86,7 @@ func (c *Client) Set(key string, val string) (interface{}, error) { if err != nil { return nil, err } - if len(resp) == 2 && resp[0] == "ok" { + if len(resp) > 0 && resp[0] == "ok" { return true, nil } return nil, fmt.Errorf("bad response") From 65b123c2ad686a4ca6ce9b1841108519a5695068 Mon Sep 17 00:00:00 2001 From: Brian McQueen Date: Sun, 18 Jan 2015 16:45:45 -0800 Subject: [PATCH 09/14] change 2 more == 2 to > 0 --- ssdb/ssdb.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ssdb/ssdb.go b/ssdb/ssdb.go index 890a76a..4331d25 100644 --- a/ssdb/ssdb.go +++ b/ssdb/ssdb.go @@ -107,7 +107,7 @@ func (c *Client) Get(key string) (interface{}, error) { if err != nil { return nil, err } - if len(resp) == 2 && resp[0] == "ok" { + if len(resp) > 0 && resp[0] == "ok" { return resp[1], nil } if resp[0] == "not_found" { @@ -131,7 +131,7 @@ func (c *Client) Del(key string) (interface{}, error) { } //response looks like this: [ok 1] - if len(resp) == 2 && resp[0] == "ok" { + if len(resp) > 0 && resp[0] == "ok" { return true, nil } return nil, fmt.Errorf("bad response:resp:%v:", resp) From 4e61e4b4121180e764fa6a1ec95488a8baf576a2 Mon Sep 17 00:00:00 2001 From: Brian McQueen Date: Sun, 18 Jan 2015 17:31:04 -0800 Subject: [PATCH 10/14] removed an external dependency between parse and recv via the Client struct - made private method parse into function - exposed apis are unchanged --- ssdb/ssdb.go | 18 ++++++++++-------- ssdb/ssdb_test.go | 9 ++++++--- 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/ssdb/ssdb.go b/ssdb/ssdb.go index 4331d25..bfe8088 100644 --- a/ssdb/ssdb.go +++ b/ssdb/ssdb.go @@ -9,7 +9,6 @@ import ( type Client struct { sock chan *net.TCPConn - recv_buf bytes.Buffer _sock *net.TCPConn } @@ -197,6 +196,7 @@ func (c *Client) recv() ([]string, error) { var sock = c._sock var tmp [8192]byte + var recv_buf = new(bytes.Buffer) for { n, err := sock.Read(tmp[0:]) @@ -204,17 +204,19 @@ func (c *Client) recv() ([]string, error) { return nil, err } - c.recv_buf.Write(tmp[0:n]) - resp := c.parse() + + recv_buf.Write(tmp[0:n]) + resp := parse(recv_buf) if resp == nil || len(resp) > 0 { return resp, nil } } } -func (c *Client) parse() []string { - resp := []string{} - buf := c.recv_buf.Bytes() +func parse(recv_buf *bytes.Buffer) []string { + resp := []string{} + + buf := recv_buf.Bytes() var idx, offset int idx = 0 offset = 0 @@ -231,7 +233,7 @@ func (c *Client) parse() []string { if len(resp) == 0 { continue } else { - c.recv_buf.Next(offset) + recv_buf.Next(offset) return resp } } @@ -240,7 +242,7 @@ func (c *Client) parse() []string { if err != nil || size < 0 { return nil } - if offset+size >= c.recv_buf.Len() { + if offset+size >= recv_buf.Len() { break } diff --git a/ssdb/ssdb_test.go b/ssdb/ssdb_test.go index 532d8b6..422e7e0 100644 --- a/ssdb/ssdb_test.go +++ b/ssdb/ssdb_test.go @@ -81,7 +81,7 @@ func TestGet(t *testing.T) { } defer db.Close() - val, err := db.Set("a", "xxx") + val, err := db.Set("a", "xxxdodoehodh eodhoe dohe j") if val != true { t.Error("Set val returned false") } @@ -96,8 +96,11 @@ func TestGet(t *testing.T) { if err != nil { t.Error("Get returned err") } - if val != "xxx" { - t.Error("Get did not return a") + if val != "xxxdodoehodh eodhoe dohe j" { + t.Error("Get did not return the right value") + } + if val == "xxx" { + t.Error("Get did not return return xxx") } } From cd811cc0e8e9000669e50c2a2917bd5753612a9b Mon Sep 17 00:00:00 2001 From: Brian McQueen Date: Sun, 18 Jan 2015 17:55:29 -0800 Subject: [PATCH 11/14] add a few more tests --- ssdb/ssdb_test.go | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/ssdb/ssdb_test.go b/ssdb/ssdb_test.go index 422e7e0..78265bd 100644 --- a/ssdb/ssdb_test.go +++ b/ssdb/ssdb_test.go @@ -29,9 +29,32 @@ func TestConnect(t *testing.T) { } defer db.Close() + db, err = Connect(ip, port) + if err != nil { + t.Error("Close:second connect raised an error:%v:", err) + } + +} + + +func TestClose(t *testing.T) { + + db, err := Connect(ip, port) + if err != nil { + t.Error("Close:connect returned an err:%v:", err) + } + if db == nil { + t.Error("Close:connect returned a nil db") + } + + db.Close() + if err != nil { + t.Error("Close:returned an error:%v:", err) + } + } -func QTestInitPool(t *testing.T) { +func TestInitPool(t *testing.T) { cpm, err := InitPool(ip, port, 11) if err != nil { From 56ab7a055c119d21e58864d26827078dbf4dc83a Mon Sep 17 00:00:00 2001 From: Brian McQueen Date: Sun, 18 Jan 2015 18:36:11 -0800 Subject: [PATCH 12/14] added more examples --- test.go | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/test.go b/test.go index 34ac04f..0e71afa 100644 --- a/test.go +++ b/test.go @@ -28,6 +28,24 @@ func main() { os.Exit(1) } + val, err = db.Do("info"); + fmt.Printf("called info:%s:\n", val); + if err != nil { + os.Exit(1) + } + + val, err = db.Do("keys", "", "", 100); + fmt.Printf("called keys:%s:\n", val); + if err != nil { + os.Exit(1) + } + + val, err = db.Do("scan", "", "", 100); + fmt.Printf("called scan:%s:\n", val); + if err != nil { + os.Exit(1) + } + db.Set("a", "xxx") val, err = db.Get("a") fmt.Printf("Got:%v:\n", val) From ebef51c21ef8d50d77d79a9baa05cbf57be16836 Mon Sep 17 00:00:00 2001 From: Brian McQueen Date: Sun, 18 Jan 2015 21:33:48 -0800 Subject: [PATCH 13/14] added Info method and more tests --- ssdb/ssdb.go | 15 +++++++++++++++ ssdb/ssdb_test.go | 11 +++++++++++ test.go | 6 ++++++ 3 files changed, 32 insertions(+) diff --git a/ssdb/ssdb.go b/ssdb/ssdb.go index bfe8088..2f5344a 100644 --- a/ssdb/ssdb.go +++ b/ssdb/ssdb.go @@ -107,6 +107,7 @@ func (c *Client) Get(key string) (interface{}, error) { return nil, err } if len(resp) > 0 && resp[0] == "ok" { + // return resp[1], nil return resp[1], nil } if resp[0] == "not_found" { @@ -115,6 +116,20 @@ func (c *Client) Get(key string) (interface{}, error) { return nil, fmt.Errorf("bad response") } +func (c *Client) Info() (interface{}, error) { + resp, err := c.Do("info") + if err != nil { + return nil, err + } + if len(resp) > 0 && resp[0] == "ok" { + return resp, nil + } + if resp[0] == "not_found" { + return nil, nil + } + return nil, fmt.Errorf("bad response") +} + func (c *ConnectionPoolWrapper) Get(key string) (interface{}, error) { db := c.GetConnection() diff --git a/ssdb/ssdb_test.go b/ssdb/ssdb_test.go index 78265bd..a004afe 100644 --- a/ssdb/ssdb_test.go +++ b/ssdb/ssdb_test.go @@ -52,6 +52,17 @@ func TestClose(t *testing.T) { t.Error("Close:returned an error:%v:", err) } + val, err := db.Set("a", "xxx") + if val == true { + t.Error("Close:Set:val returned true after db closed") + } + if val != nil { + t.Error("Close:Set:val returned non-nil after db closed") + } + if err == nil { + t.Error("Close:Set returned no error after db closed") + } + } func TestInitPool(t *testing.T) { diff --git a/test.go b/test.go index 0e71afa..178faa1 100644 --- a/test.go +++ b/test.go @@ -34,6 +34,12 @@ func main() { os.Exit(1) } + val, err = db.Info(); + fmt.Printf("called info again:%s:\n", val); + if err != nil { + os.Exit(1) + } + val, err = db.Do("keys", "", "", 100); fmt.Printf("called keys:%s:\n", val); if err != nil { From 83c8dfe8afa7f6a22910c8daec36042b62754e6a Mon Sep 17 00:00:00 2001 From: Brian McQueen Date: Sun, 18 Jan 2015 21:39:39 -0800 Subject: [PATCH 14/14] Revert "removed an external dependency between parse and recv via the Client struct - made private method parse into function - exposed apis are unchanged" This reverts commit 4e61e4b4121180e764fa6a1ec95488a8baf576a2. --- ssdb/ssdb.go | 18 ++++++++---------- ssdb/ssdb_test.go | 9 +++------ 2 files changed, 11 insertions(+), 16 deletions(-) diff --git a/ssdb/ssdb.go b/ssdb/ssdb.go index 2f5344a..81b2831 100644 --- a/ssdb/ssdb.go +++ b/ssdb/ssdb.go @@ -9,6 +9,7 @@ import ( type Client struct { sock chan *net.TCPConn + recv_buf bytes.Buffer _sock *net.TCPConn } @@ -211,7 +212,6 @@ func (c *Client) recv() ([]string, error) { var sock = c._sock var tmp [8192]byte - var recv_buf = new(bytes.Buffer) for { n, err := sock.Read(tmp[0:]) @@ -219,19 +219,17 @@ func (c *Client) recv() ([]string, error) { return nil, err } - - recv_buf.Write(tmp[0:n]) - resp := parse(recv_buf) + c.recv_buf.Write(tmp[0:n]) + resp := c.parse() if resp == nil || len(resp) > 0 { return resp, nil } } } -func parse(recv_buf *bytes.Buffer) []string { - resp := []string{} - - buf := recv_buf.Bytes() +func (c *Client) parse() []string { + resp := []string{} + buf := c.recv_buf.Bytes() var idx, offset int idx = 0 offset = 0 @@ -248,7 +246,7 @@ func parse(recv_buf *bytes.Buffer) []string { if len(resp) == 0 { continue } else { - recv_buf.Next(offset) + c.recv_buf.Next(offset) return resp } } @@ -257,7 +255,7 @@ func parse(recv_buf *bytes.Buffer) []string { if err != nil || size < 0 { return nil } - if offset+size >= recv_buf.Len() { + if offset+size >= c.recv_buf.Len() { break } diff --git a/ssdb/ssdb_test.go b/ssdb/ssdb_test.go index a004afe..1ef3e83 100644 --- a/ssdb/ssdb_test.go +++ b/ssdb/ssdb_test.go @@ -115,7 +115,7 @@ func TestGet(t *testing.T) { } defer db.Close() - val, err := db.Set("a", "xxxdodoehodh eodhoe dohe j") + val, err := db.Set("a", "xxx") if val != true { t.Error("Set val returned false") } @@ -130,11 +130,8 @@ func TestGet(t *testing.T) { if err != nil { t.Error("Get returned err") } - if val != "xxxdodoehodh eodhoe dohe j" { - t.Error("Get did not return the right value") - } - if val == "xxx" { - t.Error("Get did not return return xxx") + if val != "xxx" { + t.Error("Get did not return a") } }