pool_test.go 3.5 KB

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