@@ -1749,3 +1749,159 @@ func TestSentinelClientLoadingRetry(t *testing.T) {
1749
1749
}
1750
1750
})
1751
1751
}
1752
+
1753
+ func TestSentinelClientConnLifetime (t * testing.T ) {
1754
+ defer ShouldNotLeaked (SetupLeakDetection ())
1755
+
1756
+ setup := func () (* sentinelClient , * mockConn , * mockConn ) {
1757
+ s0 := & mockConn {
1758
+ DoFn : func (cmd Completed ) RedisResult { return RedisResult {} },
1759
+ DoMultiFn : func (multi ... Completed ) * redisresults {
1760
+ return & redisresults {s : []RedisResult {
1761
+ {val : slicemsg ('*' , []RedisMessage {})},
1762
+ {val : slicemsg ('*' , []RedisMessage {
1763
+ strmsg ('+' , "" ), strmsg ('+' , "1" ),
1764
+ })},
1765
+ }}
1766
+ },
1767
+ }
1768
+ m1 := & mockConn {
1769
+ DoFn : func (cmd Completed ) RedisResult {
1770
+ if cmd == cmds .RoleCmd {
1771
+ return RedisResult {val : slicemsg ('*' , []RedisMessage {strmsg ('+' , "master" )})}
1772
+ }
1773
+ return RedisResult {}
1774
+ },
1775
+ AddrFn : func () string { return ":1" },
1776
+ }
1777
+ client , err := newSentinelClient (
1778
+ & ClientOption {InitAddress : []string {":0" }, ConnLifetime : 1 * time .Second },
1779
+ func (dst string , opt * ClientOption ) conn {
1780
+ if dst == ":0" {
1781
+ return s0
1782
+ }
1783
+ if dst == ":1" {
1784
+ return m1
1785
+ }
1786
+ return nil
1787
+ },
1788
+ newRetryer (defaultRetryDelayFn ),
1789
+ )
1790
+ if err != nil {
1791
+ t .Fatalf ("unexpected err %v" , err )
1792
+ }
1793
+ return client , s0 , m1
1794
+ }
1795
+
1796
+ t .Run ("Do ConnLifetime" , func (t * testing.T ) {
1797
+ client , _ , m := setup ()
1798
+ var attempts int64
1799
+ m .DoFn = func (cmd Completed ) RedisResult {
1800
+ if atomic .AddInt64 (& attempts , 1 ) == 1 {
1801
+ return newErrResult (errConnExpired )
1802
+ }
1803
+ return newResult (strmsg ('+' , "OK" ), nil )
1804
+ }
1805
+ if v , err := client .Do (context .Background (), client .B ().Get ().Key ("Do" ).Build ()).ToString (); err != nil || v != "OK" {
1806
+ t .Fatalf ("unexpected response %v %v" , v , err )
1807
+ }
1808
+ })
1809
+
1810
+ t .Run ("DoCache ConnLifetime" , func (t * testing.T ) {
1811
+ client , _ , m := setup ()
1812
+ var attempts int64
1813
+ m .DoCacheFn = func (cmd Cacheable , ttl time.Duration ) RedisResult {
1814
+ if atomic .AddInt64 (& attempts , 1 ) == 1 {
1815
+ return newErrResult (errConnExpired )
1816
+ }
1817
+ return newResult (strmsg ('+' , "OK" ), nil )
1818
+ }
1819
+ if v , err := client .DoCache (context .Background (), client .B ().Get ().Key ("Do" ).Cache (), 0 ).ToString (); err != nil || v != "OK" {
1820
+ t .Fatalf ("unexpected response %v %v" , v , err )
1821
+ }
1822
+ })
1823
+
1824
+ t .Run ("DoMulti ConnLifetime - at the head of processing" , func (t * testing.T ) {
1825
+ client , _ , m := setup ()
1826
+ var attempts int64
1827
+ m .DoMultiFn = func (multi ... Completed ) * redisresults {
1828
+ if atomic .AddInt64 (& attempts , 1 ) == 1 {
1829
+ return & redisresults {s : []RedisResult {newErrResult (errConnExpired )}}
1830
+ }
1831
+ return & redisresults {s : []RedisResult {newResult (strmsg ('+' , "OK" ), nil )}}
1832
+ }
1833
+ if v , err := client .DoMulti (context .Background (), client .B ().Get ().Key ("Do" ).Build ())[0 ].ToString (); err != nil || v != "OK" {
1834
+ t .Fatalf ("unexpected response %v %v" , v , err )
1835
+ }
1836
+ })
1837
+
1838
+ t .Run ("DoMulti ConnLifetime - in the middle of processing" , func (t * testing.T ) {
1839
+ client , _ , m := setup ()
1840
+ var attempts int64
1841
+ m .DoMultiFn = func (multi ... Completed ) * redisresults {
1842
+ if atomic .AddInt64 (& attempts , 1 ) == 1 {
1843
+ return & redisresults {s : []RedisResult {newResult (strmsg ('+' , "OK" ), nil ), newErrResult (errConnExpired )}}
1844
+ }
1845
+ return & redisresults {s : []RedisResult {newResult (strmsg ('+' , "OK" ), nil )}}
1846
+ }
1847
+ resps := client .DoMulti (context .Background (), client .B ().Get ().Key ("Do" ).Build (), client .B ().Get ().Key ("Do" ).Build ())
1848
+ if len (resps ) != 2 {
1849
+ t .Errorf ("unexpected response length %v" , len (resps ))
1850
+ }
1851
+ for _ , resp := range resps {
1852
+ if v , err := resp .ToString (); err != nil || v != "OK" {
1853
+ t .Fatalf ("unexpected response %v %v" , v , err )
1854
+ }
1855
+ }
1856
+ })
1857
+
1858
+ t .Run ("DoMultiCache ConnLifetime - at the head of processing" , func (t * testing.T ) {
1859
+ client , _ , m := setup ()
1860
+ var attempts int64
1861
+ m .DoMultiCacheFn = func (multi ... CacheableTTL ) * redisresults {
1862
+ if atomic .AddInt64 (& attempts , 1 ) == 1 {
1863
+ return & redisresults {s : []RedisResult {newErrResult (errConnExpired )}}
1864
+ }
1865
+ return & redisresults {s : []RedisResult {newResult (strmsg ('+' , "OK" ), nil )}}
1866
+ }
1867
+ if v , err := client .DoMultiCache (context .Background (), CT (client .B ().Get ().Key ("Do" ).Cache (), 0 ))[0 ].ToString (); err != nil || v != "OK" {
1868
+ t .Fatalf ("unexpected response %v %v" , v , err )
1869
+ }
1870
+ })
1871
+
1872
+ t .Run ("DoMultiCache ConnLifetime - in the middle of processing" , func (t * testing.T ) {
1873
+ client , _ , m := setup ()
1874
+ var attempts int64
1875
+ m .DoMultiCacheFn = func (multi ... CacheableTTL ) * redisresults {
1876
+ if atomic .AddInt64 (& attempts , 1 ) == 1 {
1877
+ return & redisresults {s : []RedisResult {newResult (strmsg ('+' , "OK" ), nil ), newErrResult (errConnExpired )}}
1878
+ }
1879
+ return & redisresults {s : []RedisResult {newResult (strmsg ('+' , "OK" ), nil )}}
1880
+ }
1881
+ resps := client .DoMultiCache (context .Background (), CT (client .B ().Get ().Key ("Do" ).Cache (), 0 ), CT (client .B ().Get ().Key ("Do" ).Cache (), 0 ))
1882
+ if len (resps ) != 2 {
1883
+ t .Errorf ("unexpected response length %v" , len (resps ))
1884
+ }
1885
+ for _ , resp := range resps {
1886
+ if v , err := resp .ToString (); err != nil || v != "OK" {
1887
+ t .Fatalf ("unexpected response %v %v" , v , err )
1888
+ }
1889
+ }
1890
+ })
1891
+
1892
+ t .Run ("Receive ConnLifetime" , func (t * testing.T ) {
1893
+ client , _ , m := setup ()
1894
+ c := client .B ().Subscribe ().Channel ("ch" ).Build ()
1895
+ hdl := func (message PubSubMessage ) {}
1896
+ var attempts int64
1897
+ m .ReceiveFn = func (ctx context.Context , subscribe Completed , fn func (message PubSubMessage )) error {
1898
+ if atomic .AddInt64 (& attempts , 1 ) == 1 {
1899
+ return errConnExpired
1900
+ }
1901
+ return nil
1902
+ }
1903
+ if err := client .Receive (context .Background (), c , hdl ); err != nil {
1904
+ t .Fatalf ("unexpected response %v" , err )
1905
+ }
1906
+ })
1907
+ }
0 commit comments