Skip to content

Commit ad0739b

Browse files
committed
Extract pool package. Add pool benchmark.
1 parent aad4561 commit ad0739b

25 files changed

+969
-898
lines changed

bench_test.go

Lines changed: 54 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,15 @@ package redis_test
22

33
import (
44
"bytes"
5+
"errors"
6+
"net"
57
"testing"
68
"time"
79

810
redigo "github.com/garyburd/redigo/redis"
911

1012
"gopkg.in/redis.v3"
13+
"gopkg.in/redis.v3/internal/pool"
1114
)
1215

1316
func benchmarkRedisClient(poolSize int) *redis.Client {
@@ -274,11 +277,11 @@ func BenchmarkZAdd(b *testing.B) {
274277
})
275278
}
276279

277-
func BenchmarkPool(b *testing.B) {
278-
client := benchmarkRedisClient(10)
279-
defer client.Close()
280-
281-
pool := client.Pool()
280+
func benchmarkPoolGetPut(b *testing.B, poolSize int) {
281+
dial := func() (*pool.Conn, error) {
282+
return pool.NewConn(&net.TCPConn{}), nil
283+
}
284+
pool := pool.NewConnPool(dial, poolSize, time.Second, 0)
282285

283286
b.ResetTimer()
284287

@@ -294,3 +297,49 @@ func BenchmarkPool(b *testing.B) {
294297
}
295298
})
296299
}
300+
301+
func BenchmarkPoolGetPut10Conns(b *testing.B) {
302+
benchmarkPoolGetPut(b, 10)
303+
}
304+
305+
func BenchmarkPoolGetPut100Conns(b *testing.B) {
306+
benchmarkPoolGetPut(b, 100)
307+
}
308+
309+
func BenchmarkPoolGetPut1000Conns(b *testing.B) {
310+
benchmarkPoolGetPut(b, 1000)
311+
}
312+
313+
func benchmarkPoolGetRemove(b *testing.B, poolSize int) {
314+
dial := func() (*pool.Conn, error) {
315+
return pool.NewConn(&net.TCPConn{}), nil
316+
}
317+
pool := pool.NewConnPool(dial, poolSize, time.Second, 0)
318+
removeReason := errors.New("benchmark")
319+
320+
b.ResetTimer()
321+
322+
b.RunParallel(func(pb *testing.PB) {
323+
for pb.Next() {
324+
conn, _, err := pool.Get()
325+
if err != nil {
326+
b.Fatalf("no error expected on pool.Get but received: %s", err.Error())
327+
}
328+
if err = pool.Remove(conn, removeReason); err != nil {
329+
b.Fatalf("no error expected on pool.Remove but received: %s", err.Error())
330+
}
331+
}
332+
})
333+
}
334+
335+
func BenchmarkPoolGetRemove10Conns(b *testing.B) {
336+
benchmarkPoolGetRemove(b, 10)
337+
}
338+
339+
func BenchmarkPoolGetRemove100Conns(b *testing.B) {
340+
benchmarkPoolGetRemove(b, 100)
341+
}
342+
343+
func BenchmarkPoolGetRemove1000Conns(b *testing.B) {
344+
benchmarkPoolGetRemove(b, 1000)
345+
}

cluster_pipeline.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package redis
22

33
import (
44
"gopkg.in/redis.v3/internal/hashtag"
5+
"gopkg.in/redis.v3/internal/pool"
56
)
67

78
// ClusterPipeline is not thread-safe.
@@ -96,9 +97,9 @@ func (pipe *ClusterPipeline) Close() error {
9697
}
9798

9899
func (pipe *ClusterPipeline) execClusterCmds(
99-
cn *conn, cmds []Cmder, failedCmds map[string][]Cmder,
100+
cn *pool.Conn, cmds []Cmder, failedCmds map[string][]Cmder,
100101
) (map[string][]Cmder, error) {
101-
if err := cn.writeCmds(cmds...); err != nil {
102+
if err := writeCmd(cn, cmds...); err != nil {
102103
setCmdsErr(cmds, err)
103104
return failedCmds, err
104105
}

command.go

Lines changed: 38 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import (
66
"strconv"
77
"strings"
88
"time"
9+
10+
"gopkg.in/redis.v3/internal/pool"
911
)
1012

1113
var (
@@ -28,7 +30,7 @@ var (
2830

2931
type Cmder interface {
3032
args() []interface{}
31-
readReply(*conn) error
33+
readReply(*pool.Conn) error
3234
setErr(error)
3335
reset()
3436

@@ -51,6 +53,20 @@ func resetCmds(cmds []Cmder) {
5153
}
5254
}
5355

56+
func writeCmd(cn *pool.Conn, cmds ...Cmder) error {
57+
cn.Buf = cn.Buf[:0]
58+
for _, cmd := range cmds {
59+
var err error
60+
cn.Buf, err = appendArgs(cn.Buf, cmd.args())
61+
if err != nil {
62+
return err
63+
}
64+
}
65+
66+
_, err := cn.Write(cn.Buf)
67+
return err
68+
}
69+
5470
func cmdString(cmd Cmder, val interface{}) string {
5571
var ss []string
5672
for _, arg := range cmd.args() {
@@ -143,7 +159,7 @@ func (cmd *Cmd) String() string {
143159
return cmdString(cmd, cmd.val)
144160
}
145161

146-
func (cmd *Cmd) readReply(cn *conn) error {
162+
func (cmd *Cmd) readReply(cn *pool.Conn) error {
147163
val, err := readReply(cn, sliceParser)
148164
if err != nil {
149165
cmd.err = err
@@ -188,7 +204,7 @@ func (cmd *SliceCmd) String() string {
188204
return cmdString(cmd, cmd.val)
189205
}
190206

191-
func (cmd *SliceCmd) readReply(cn *conn) error {
207+
func (cmd *SliceCmd) readReply(cn *pool.Conn) error {
192208
v, err := readArrayReply(cn, sliceParser)
193209
if err != nil {
194210
cmd.err = err
@@ -231,7 +247,7 @@ func (cmd *StatusCmd) String() string {
231247
return cmdString(cmd, cmd.val)
232248
}
233249

234-
func (cmd *StatusCmd) readReply(cn *conn) error {
250+
func (cmd *StatusCmd) readReply(cn *pool.Conn) error {
235251
cmd.val, cmd.err = readStringReply(cn)
236252
return cmd.err
237253
}
@@ -265,7 +281,7 @@ func (cmd *IntCmd) String() string {
265281
return cmdString(cmd, cmd.val)
266282
}
267283

268-
func (cmd *IntCmd) readReply(cn *conn) error {
284+
func (cmd *IntCmd) readReply(cn *pool.Conn) error {
269285
cmd.val, cmd.err = readIntReply(cn)
270286
return cmd.err
271287
}
@@ -303,7 +319,7 @@ func (cmd *DurationCmd) String() string {
303319
return cmdString(cmd, cmd.val)
304320
}
305321

306-
func (cmd *DurationCmd) readReply(cn *conn) error {
322+
func (cmd *DurationCmd) readReply(cn *pool.Conn) error {
307323
n, err := readIntReply(cn)
308324
if err != nil {
309325
cmd.err = err
@@ -344,7 +360,7 @@ func (cmd *BoolCmd) String() string {
344360

345361
var ok = []byte("OK")
346362

347-
func (cmd *BoolCmd) readReply(cn *conn) error {
363+
func (cmd *BoolCmd) readReply(cn *pool.Conn) error {
348364
v, err := readReply(cn, nil)
349365
// `SET key value NX` returns nil when key already exists. But
350366
// `SETNX key value` returns bool (0/1). So convert nil to bool.
@@ -430,13 +446,17 @@ func (cmd *StringCmd) String() string {
430446
return cmdString(cmd, cmd.val)
431447
}
432448

433-
func (cmd *StringCmd) readReply(cn *conn) error {
449+
func (cmd *StringCmd) readReply(cn *pool.Conn) error {
434450
b, err := readBytesReply(cn)
435451
if err != nil {
436452
cmd.err = err
437453
return err
438454
}
439-
cmd.val = cn.copyBuf(b)
455+
456+
new := make([]byte, len(b))
457+
copy(new, b)
458+
cmd.val = new
459+
440460
return nil
441461
}
442462

@@ -469,7 +489,7 @@ func (cmd *FloatCmd) String() string {
469489
return cmdString(cmd, cmd.val)
470490
}
471491

472-
func (cmd *FloatCmd) readReply(cn *conn) error {
492+
func (cmd *FloatCmd) readReply(cn *pool.Conn) error {
473493
cmd.val, cmd.err = readFloatReply(cn)
474494
return cmd.err
475495
}
@@ -503,7 +523,7 @@ func (cmd *StringSliceCmd) String() string {
503523
return cmdString(cmd, cmd.val)
504524
}
505525

506-
func (cmd *StringSliceCmd) readReply(cn *conn) error {
526+
func (cmd *StringSliceCmd) readReply(cn *pool.Conn) error {
507527
v, err := readArrayReply(cn, stringSliceParser)
508528
if err != nil {
509529
cmd.err = err
@@ -542,7 +562,7 @@ func (cmd *BoolSliceCmd) String() string {
542562
return cmdString(cmd, cmd.val)
543563
}
544564

545-
func (cmd *BoolSliceCmd) readReply(cn *conn) error {
565+
func (cmd *BoolSliceCmd) readReply(cn *pool.Conn) error {
546566
v, err := readArrayReply(cn, boolSliceParser)
547567
if err != nil {
548568
cmd.err = err
@@ -581,7 +601,7 @@ func (cmd *StringStringMapCmd) String() string {
581601
return cmdString(cmd, cmd.val)
582602
}
583603

584-
func (cmd *StringStringMapCmd) readReply(cn *conn) error {
604+
func (cmd *StringStringMapCmd) readReply(cn *pool.Conn) error {
585605
v, err := readArrayReply(cn, stringStringMapParser)
586606
if err != nil {
587607
cmd.err = err
@@ -620,7 +640,7 @@ func (cmd *StringIntMapCmd) reset() {
620640
cmd.err = nil
621641
}
622642

623-
func (cmd *StringIntMapCmd) readReply(cn *conn) error {
643+
func (cmd *StringIntMapCmd) readReply(cn *pool.Conn) error {
624644
v, err := readArrayReply(cn, stringIntMapParser)
625645
if err != nil {
626646
cmd.err = err
@@ -659,7 +679,7 @@ func (cmd *ZSliceCmd) String() string {
659679
return cmdString(cmd, cmd.val)
660680
}
661681

662-
func (cmd *ZSliceCmd) readReply(cn *conn) error {
682+
func (cmd *ZSliceCmd) readReply(cn *pool.Conn) error {
663683
v, err := readArrayReply(cn, zSliceParser)
664684
if err != nil {
665685
cmd.err = err
@@ -703,7 +723,7 @@ func (cmd *ScanCmd) String() string {
703723
return cmdString(cmd, cmd.keys)
704724
}
705725

706-
func (cmd *ScanCmd) readReply(cn *conn) error {
726+
func (cmd *ScanCmd) readReply(cn *pool.Conn) error {
707727
keys, cursor, err := readScanReply(cn)
708728
if err != nil {
709729
cmd.err = err
@@ -751,7 +771,7 @@ func (cmd *ClusterSlotCmd) reset() {
751771
cmd.err = nil
752772
}
753773

754-
func (cmd *ClusterSlotCmd) readReply(cn *conn) error {
774+
func (cmd *ClusterSlotCmd) readReply(cn *pool.Conn) error {
755775
v, err := readArrayReply(cn, clusterSlotInfoSliceParser)
756776
if err != nil {
757777
cmd.err = err
@@ -838,7 +858,7 @@ func (cmd *GeoLocationCmd) String() string {
838858
return cmdString(cmd, cmd.locations)
839859
}
840860

841-
func (cmd *GeoLocationCmd) readReply(cn *conn) error {
861+
func (cmd *GeoLocationCmd) readReply(cn *pool.Conn) error {
842862
reply, err := readArrayReply(cn, newGeoLocationSliceParser(cmd.q))
843863
if err != nil {
844864
cmd.err = err

0 commit comments

Comments
 (0)