@@ -567,4 +567,104 @@ var _ = Describe("PubSub", func() {
567
567
Expect (msg .Channel ).To (Equal ("mychannel" ))
568
568
Expect (msg .Payload ).To (Equal (text ))
569
569
})
570
+
571
+ It ("should not use connections from pool" , func () {
572
+ statsBefore := client .PoolStats ()
573
+
574
+ pubsub := client .Subscribe (ctx , "mychannel" )
575
+ defer pubsub .Close ()
576
+
577
+ stats := client .PoolStats ()
578
+ // A connection has been created
579
+ Expect (stats .TotalConns - statsBefore .TotalConns ).To (Equal (uint32 (1 )))
580
+ // But it's not taken from the pool
581
+ poolFetchesBefore := statsBefore .Hits + statsBefore .Misses
582
+ poolFetchesAfter := stats .Hits + stats .Misses
583
+ Expect (poolFetchesAfter - poolFetchesBefore ).To (Equal (uint32 (0 )))
584
+
585
+ pubsub .Close ()
586
+
587
+ stats = client .PoolStats ()
588
+ // The connection no longer exists
589
+ Expect (stats .TotalConns - statsBefore .TotalConns ).To (Equal (uint32 (0 )))
590
+ Expect (stats .IdleConns - statsBefore .IdleConns ).To (Equal (uint32 (0 )))
591
+ })
592
+ })
593
+
594
+ var _ = Describe ("PubSub with PubsubFromPool set" , func () {
595
+ var client * redis.Client
596
+
597
+ BeforeEach (func () {
598
+ opt := redisOptions ()
599
+ opt .MinIdleConns = 0
600
+ opt .ConnMaxLifetime = 0
601
+ opt .PubsubFromPool = true
602
+ // zero value ends up using default so set small instead
603
+ opt .PoolTimeout = time .Microsecond
604
+ client = redis .NewClient (opt )
605
+ Expect (client .FlushDB (ctx ).Err ()).NotTo (HaveOccurred ())
606
+ })
607
+
608
+ AfterEach (func () {
609
+ Expect (client .Close ()).NotTo (HaveOccurred ())
610
+ })
611
+
612
+ It ("should use connection from pool" , func () {
613
+ statsBefore := client .PoolStats ()
614
+
615
+ pubsub := client .Subscribe (ctx , "mychannel" )
616
+ defer pubsub .Close ()
617
+
618
+ stats := client .PoolStats ()
619
+ // A connection has been taken from the pool
620
+ Expect (stats .Hits - statsBefore .Hits ).To (Equal (uint32 (1 )))
621
+ statsDuring := client .PoolStats ()
622
+
623
+ pubsub .Close ()
624
+
625
+ stats = client .PoolStats ()
626
+ // It's not returned to the idle pool ..
627
+ Expect (statsDuring .IdleConns - stats .IdleConns ).To (Equal (uint32 (0 )))
628
+ // .. and has been terminated
629
+ Expect (statsDuring .TotalConns - stats .TotalConns ).To (Equal (uint32 (1 )))
630
+ })
631
+
632
+ It ("should respect pool size limit" , func () {
633
+ poolSize := client .Options ().PoolSize
634
+ statsBefore := client .PoolStats ()
635
+
636
+ var pubsubs []* redis.PubSub
637
+ for i := 0 ; i < poolSize ; i ++ {
638
+ pubsub := client .Subscribe (ctx , "mychannel" )
639
+ defer pubsub .Close ()
640
+ pubsubs = append (pubsubs , pubsub )
641
+ }
642
+
643
+ statsDuring := client .PoolStats ()
644
+ poolFetchesBefore := statsBefore .Hits + statsBefore .Misses
645
+ poolFetchesAfter := statsDuring .Hits + statsDuring .Misses
646
+
647
+ // A total of poolSize connections should have been taken from the pool (new or existing)
648
+ Expect (poolFetchesAfter - poolFetchesBefore ).To (Equal (uint32 (poolSize )))
649
+
650
+ // The next pubsub connection should fail to connect (waiting for pool)
651
+ extraPubsub := client .Subscribe (ctx , "mychannel" )
652
+ defer extraPubsub .Close ()
653
+ Expect (client .PoolStats ().Timeouts - statsDuring .Timeouts ).To (Equal (uint32 (1 )))
654
+
655
+ // As should retries
656
+ err := extraPubsub .Ping (ctx )
657
+ Expect (err ).To (MatchError (ContainSubstring ("connection pool timeout" )))
658
+ Expect (client .PoolStats ().Timeouts - statsDuring .Timeouts ).To (Equal (uint32 (2 )))
659
+
660
+ for _ , pubsub := range pubsubs {
661
+ pubsub .Close ()
662
+ }
663
+
664
+ stats := client .PoolStats ()
665
+ // Connections are not returned to the idle pool ..
666
+ Expect (statsDuring .IdleConns - stats .IdleConns ).To (Equal (uint32 (0 )))
667
+ // .. and have been terminated
668
+ Expect (statsDuring .TotalConns - stats .TotalConns ).To (Equal (uint32 (poolSize )))
669
+ })
570
670
})
0 commit comments