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