...
1 package redis_test
2
3 import (
4 "time"
5
6 "github.com/go-redis/redis"
7
8 . "github.com/onsi/ginkgo"
9 . "github.com/onsi/gomega"
10 )
11
12 var _ = Describe("pool", func() {
13 var client *redis.Client
14
15 BeforeEach(func() {
16 opt := redisOptions()
17 opt.MinIdleConns = 0
18 opt.MaxConnAge = 0
19 client = redis.NewClient(opt)
20 Expect(client.FlushDB().Err()).NotTo(HaveOccurred())
21 })
22
23 AfterEach(func() {
24 Expect(client.Close()).NotTo(HaveOccurred())
25 })
26
27 It("respects max size", func() {
28 perform(1000, func(id int) {
29 val, err := client.Ping().Result()
30 Expect(err).NotTo(HaveOccurred())
31 Expect(val).To(Equal("PONG"))
32 })
33
34 pool := client.Pool()
35 Expect(pool.Len()).To(BeNumerically("<=", 10))
36 Expect(pool.IdleLen()).To(BeNumerically("<=", 10))
37 Expect(pool.Len()).To(Equal(pool.IdleLen()))
38 })
39
40 It("respects max size on multi", func() {
41 perform(1000, func(id int) {
42 var ping *redis.StatusCmd
43
44 err := client.Watch(func(tx *redis.Tx) error {
45 cmds, err := tx.Pipelined(func(pipe redis.Pipeliner) error {
46 ping = pipe.Ping()
47 return nil
48 })
49 Expect(err).NotTo(HaveOccurred())
50 Expect(cmds).To(HaveLen(1))
51 return err
52 })
53 Expect(err).NotTo(HaveOccurred())
54
55 Expect(ping.Err()).NotTo(HaveOccurred())
56 Expect(ping.Val()).To(Equal("PONG"))
57 })
58
59 pool := client.Pool()
60 Expect(pool.Len()).To(BeNumerically("<=", 10))
61 Expect(pool.IdleLen()).To(BeNumerically("<=", 10))
62 Expect(pool.Len()).To(Equal(pool.IdleLen()))
63 })
64
65 It("respects max size on pipelines", func() {
66 perform(1000, func(id int) {
67 pipe := client.Pipeline()
68 ping := pipe.Ping()
69 cmds, err := pipe.Exec()
70 Expect(err).NotTo(HaveOccurred())
71 Expect(cmds).To(HaveLen(1))
72 Expect(ping.Err()).NotTo(HaveOccurred())
73 Expect(ping.Val()).To(Equal("PONG"))
74 Expect(pipe.Close()).NotTo(HaveOccurred())
75 })
76
77 pool := client.Pool()
78 Expect(pool.Len()).To(BeNumerically("<=", 10))
79 Expect(pool.IdleLen()).To(BeNumerically("<=", 10))
80 Expect(pool.Len()).To(Equal(pool.IdleLen()))
81 })
82
83 It("removes broken connections", func() {
84 cn, err := client.Pool().Get()
85 Expect(err).NotTo(HaveOccurred())
86 cn.SetNetConn(&badConn{})
87 client.Pool().Put(cn)
88
89 err = client.Ping().Err()
90 Expect(err).To(MatchError("bad connection"))
91
92 val, err := client.Ping().Result()
93 Expect(err).NotTo(HaveOccurred())
94 Expect(val).To(Equal("PONG"))
95
96 pool := client.Pool()
97 Expect(pool.Len()).To(Equal(1))
98 Expect(pool.IdleLen()).To(Equal(1))
99
100 stats := pool.Stats()
101 Expect(stats.Hits).To(Equal(uint32(2)))
102 Expect(stats.Misses).To(Equal(uint32(2)))
103 Expect(stats.Timeouts).To(Equal(uint32(0)))
104 })
105
106 It("reuses connections", func() {
107 for i := 0; i < 100; i++ {
108 val, err := client.Ping().Result()
109 Expect(err).NotTo(HaveOccurred())
110 Expect(val).To(Equal("PONG"))
111 }
112
113 pool := client.Pool()
114 Expect(pool.Len()).To(Equal(1))
115 Expect(pool.IdleLen()).To(Equal(1))
116
117 stats := pool.Stats()
118 Expect(stats.Hits).To(Equal(uint32(100)))
119 Expect(stats.Misses).To(Equal(uint32(1)))
120 Expect(stats.Timeouts).To(Equal(uint32(0)))
121 })
122
123 It("removes idle connections", func() {
124 stats := client.PoolStats()
125 Expect(stats).To(Equal(&redis.PoolStats{
126 Hits: 0,
127 Misses: 1,
128 Timeouts: 0,
129 TotalConns: 1,
130 IdleConns: 1,
131 StaleConns: 0,
132 }))
133
134 time.Sleep(2 * time.Second)
135
136 stats = client.PoolStats()
137 Expect(stats).To(Equal(&redis.PoolStats{
138 Hits: 0,
139 Misses: 1,
140 Timeouts: 0,
141 TotalConns: 0,
142 IdleConns: 0,
143 StaleConns: 1,
144 }))
145 })
146 })
147
View as plain text