@@ -36,10 +36,12 @@ function createInflightStore(): any {
3636 } ;
3737}
3838
39- function createBareConnector ( ) : any {
39+ function createBareConnector (
40+ dsn : string = "ws://root:taosdata@host1:6041,host2:6042"
41+ ) : any {
4042 const connector = Object . create ( WebSocketConnector . prototype ) as any ;
4143 connector . _timeout = 5000 ;
42- connector . _dsn = parse ( "ws://root:taosdata@host1:6041,host2:6042" ) ;
44+ connector . _dsn = parse ( dsn ) ;
4345 connector . _currentAddress = connector . _dsn . addresses [ 0 ] ;
4446 connector . _retryConfig = new RetryConfig ( 1 , 1 , 8 ) ;
4547 connector . _reconnectLock = null ;
@@ -117,7 +119,7 @@ describe("WebSocketConnector failover and retry", () => {
117119 const connector = createBareConnector ( ) ;
118120 const leastSelector = jest
119121 . spyOn ( AddressConnectionTracker . instance ( ) , "selectLeastConnected" )
120- . mockReturnValue ( 1 ) ;
122+ . mockImplementation ( ( ) => 0 ) ;
121123 const attempts : string [ ] = [ ] ;
122124 connector . sleep = jest . fn ( async ( ) => { } ) ;
123125 connector . reconnect = jest . fn ( async ( ) => {
@@ -135,16 +137,73 @@ describe("WebSocketConnector failover and retry", () => {
135137 "host1:6041" ,
136138 "host2:6042" ,
137139 ] ) ;
138- expect ( leastSelector ) . toHaveBeenCalledWith ( connector . _dsn . addresses ) ;
140+ expect ( leastSelector ) . toHaveBeenCalledWith ( [
141+ connector . _dsn . addresses [ 1 ] ,
142+ ] ) ;
139143 expect ( `${ connector . _currentAddress . host } :${ connector . _currentAddress . port } ` )
140144 . toBe ( "host2:6042" ) ;
141145 } ) ;
142146
147+ test ( "attemptReconnect does not reselect failed addresses in one reconnect round" , async ( ) => {
148+ const connector = createBareConnector (
149+ "ws://root:taosdata@host1:6041,host2:6042,host3:6043"
150+ ) ;
151+ const leastSelector = jest
152+ . spyOn ( AddressConnectionTracker . instance ( ) , "selectLeastConnected" )
153+ . mockImplementation ( ( ) => 0 ) ;
154+ const attempts : string [ ] = [ ] ;
155+ connector . sleep = jest . fn ( async ( ) => { } ) ;
156+ connector . reconnect = jest . fn ( async ( ) => {
157+ const current = connector . _currentAddress ;
158+ attempts . push ( `${ current . host } :${ current . port } ` ) ;
159+ throw new Error ( "all down" ) ;
160+ } ) ;
161+
162+ await expect ( connector . attemptReconnect ( ) ) . rejects . toThrow (
163+ "Failed to reconnect to any available address"
164+ ) ;
165+
166+ expect ( attempts ) . toEqual ( [
167+ "host1:6041" ,
168+ "host2:6042" ,
169+ "host3:6043" ,
170+ ] ) ;
171+ expect ( leastSelector ) . toHaveBeenNthCalledWith ( 1 , [
172+ connector . _dsn . addresses [ 1 ] ,
173+ connector . _dsn . addresses [ 2 ] ,
174+ ] ) ;
175+ expect ( leastSelector ) . toHaveBeenNthCalledWith ( 2 , [
176+ connector . _dsn . addresses [ 2 ] ,
177+ ] ) ;
178+ } ) ;
179+
180+ test ( "attemptReconnect keeps retrying same address for single-address dsn" , async ( ) => {
181+ const connector = createBareConnector ( "ws://root:taosdata@host1:6041" ) ;
182+ connector . _retryConfig = new RetryConfig ( 3 , 1 , 8 ) ;
183+ connector . sleep = jest . fn ( async ( ) => { } ) ;
184+ const attempts : string [ ] = [ ] ;
185+ connector . reconnect = jest . fn ( async ( ) => {
186+ const current = connector . _currentAddress ;
187+ attempts . push ( `${ current . host } :${ current . port } ` ) ;
188+ throw new Error ( "host1 down" ) ;
189+ } ) ;
190+
191+ await expect ( connector . attemptReconnect ( ) ) . rejects . toThrow (
192+ "Failed to reconnect to any available address"
193+ ) ;
194+
195+ expect ( attempts ) . toEqual ( [
196+ "host1:6041" ,
197+ "host1:6041" ,
198+ "host1:6041" ,
199+ ] ) ;
200+ } ) ;
201+
143202 test ( "attemptReconnect throws after all addresses and retries are exhausted" , async ( ) => {
144203 const connector = createBareConnector ( ) ;
145204 jest
146205 . spyOn ( AddressConnectionTracker . instance ( ) , "selectLeastConnected" )
147- . mockReturnValue ( 1 ) ;
206+ . mockImplementation ( ( ) => 0 ) ;
148207 connector . sleep = jest . fn ( async ( ) => { } ) ;
149208 connector . reconnect = jest . fn ( async ( ) => {
150209 throw new Error ( "all down" ) ;
0 commit comments