| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150 |
- package redis_test
- import (
- "context"
- "time"
- "github.com/go-redis/redis/v7"
- . "github.com/onsi/ginkgo"
- . "github.com/onsi/gomega"
- )
- var _ = Describe("pool", func() {
- var client *redis.Client
- BeforeEach(func() {
- opt := redisOptions()
- opt.MinIdleConns = 0
- opt.MaxConnAge = 0
- opt.IdleTimeout = time.Second
- client = redis.NewClient(opt)
- })
- AfterEach(func() {
- Expect(client.Close()).NotTo(HaveOccurred())
- })
- It("respects max size", func() {
- perform(1000, func(id int) {
- val, err := client.Ping().Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(val).To(Equal("PONG"))
- })
- pool := client.Pool()
- Expect(pool.Len()).To(BeNumerically("<=", 10))
- Expect(pool.IdleLen()).To(BeNumerically("<=", 10))
- Expect(pool.Len()).To(Equal(pool.IdleLen()))
- })
- It("respects max size on multi", func() {
- perform(1000, func(id int) {
- var ping *redis.StatusCmd
- err := client.Watch(func(tx *redis.Tx) error {
- cmds, err := tx.Pipelined(func(pipe redis.Pipeliner) error {
- ping = pipe.Ping()
- return nil
- })
- Expect(err).NotTo(HaveOccurred())
- Expect(cmds).To(HaveLen(1))
- return err
- })
- Expect(err).NotTo(HaveOccurred())
- Expect(ping.Err()).NotTo(HaveOccurred())
- Expect(ping.Val()).To(Equal("PONG"))
- })
- pool := client.Pool()
- Expect(pool.Len()).To(BeNumerically("<=", 10))
- Expect(pool.IdleLen()).To(BeNumerically("<=", 10))
- Expect(pool.Len()).To(Equal(pool.IdleLen()))
- })
- It("respects max size on pipelines", func() {
- perform(1000, func(id int) {
- pipe := client.Pipeline()
- ping := pipe.Ping()
- cmds, err := pipe.Exec()
- Expect(err).NotTo(HaveOccurred())
- Expect(cmds).To(HaveLen(1))
- Expect(ping.Err()).NotTo(HaveOccurred())
- Expect(ping.Val()).To(Equal("PONG"))
- Expect(pipe.Close()).NotTo(HaveOccurred())
- })
- pool := client.Pool()
- Expect(pool.Len()).To(BeNumerically("<=", 10))
- Expect(pool.IdleLen()).To(BeNumerically("<=", 10))
- Expect(pool.Len()).To(Equal(pool.IdleLen()))
- })
- It("removes broken connections", func() {
- cn, err := client.Pool().Get(context.Background())
- Expect(err).NotTo(HaveOccurred())
- cn.SetNetConn(&badConn{})
- client.Pool().Put(cn)
- err = client.Ping().Err()
- Expect(err).To(MatchError("bad connection"))
- val, err := client.Ping().Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(val).To(Equal("PONG"))
- pool := client.Pool()
- Expect(pool.Len()).To(Equal(1))
- Expect(pool.IdleLen()).To(Equal(1))
- stats := pool.Stats()
- Expect(stats.Hits).To(Equal(uint32(1)))
- Expect(stats.Misses).To(Equal(uint32(2)))
- Expect(stats.Timeouts).To(Equal(uint32(0)))
- })
- It("reuses connections", func() {
- for i := 0; i < 100; i++ {
- val, err := client.Ping().Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(val).To(Equal("PONG"))
- }
- pool := client.Pool()
- Expect(pool.Len()).To(Equal(1))
- Expect(pool.IdleLen()).To(Equal(1))
- stats := pool.Stats()
- Expect(stats.Hits).To(Equal(uint32(99)))
- Expect(stats.Misses).To(Equal(uint32(1)))
- Expect(stats.Timeouts).To(Equal(uint32(0)))
- })
- It("removes idle connections", func() {
- err := client.Ping().Err()
- Expect(err).NotTo(HaveOccurred())
- stats := client.PoolStats()
- Expect(stats).To(Equal(&redis.PoolStats{
- Hits: 0,
- Misses: 1,
- Timeouts: 0,
- TotalConns: 1,
- IdleConns: 1,
- StaleConns: 0,
- }))
- time.Sleep(2 * time.Second)
- stats = client.PoolStats()
- Expect(stats).To(Equal(&redis.PoolStats{
- Hits: 0,
- Misses: 1,
- Timeouts: 0,
- TotalConns: 0,
- IdleConns: 0,
- StaleConns: 1,
- }))
- })
- })
|