12
12
13
13
namespace RabbitMQ . AMQP . Client
14
14
{
15
+ public interface IUriSelector
16
+ {
17
+ Uri Select ( ICollection < Uri > uris ) ;
18
+ }
19
+
20
+ public class RandomUriSelector : IUriSelector
21
+ {
22
+ public Uri Select ( ICollection < Uri > uris )
23
+ {
24
+ return uris . Skip ( Utils . RandomNext ( 0 , uris . Count ) ) . First ( ) ;
25
+ }
26
+ }
27
+
15
28
public class ConnectionSettingsBuilder
16
29
{
17
30
private string _host = "localhost" ;
@@ -27,6 +40,7 @@ public class ConnectionSettingsBuilder
27
40
private TlsSettings ? _tlsSettings = null ;
28
41
private Uri ? _uri ;
29
42
private List < Uri > ? _uris ;
43
+ private IUriSelector ? _uriSelector ;
30
44
31
45
public static ConnectionSettingsBuilder Create ( )
32
46
{
@@ -125,10 +139,16 @@ public ConnectionSettingsBuilder Uris(IEnumerable<Uri> uris)
125
139
return this ;
126
140
}
127
141
142
+ public ConnectionSettingsBuilder UriSelector ( IUriSelector uriSelector )
143
+ {
144
+ _uriSelector = uriSelector ;
145
+ return this ;
146
+ }
147
+
128
148
public ConnectionSettings Build ( )
129
149
{
130
- ValidateUris ( ) ;
131
150
// TODO this should do something similar to consolidate in the Java code
151
+ ValidateUris ( ) ;
132
152
if ( _uri is not null )
133
153
{
134
154
return new ConnectionSettings ( _uri ,
@@ -140,6 +160,7 @@ public ConnectionSettings Build()
140
160
else if ( _uris is not null )
141
161
{
142
162
return new ConnectionSettings ( _uris ,
163
+ _uriSelector ,
143
164
_containerId , _saslMechanism ,
144
165
_recoveryConfiguration ,
145
166
_maxFrameSize ,
@@ -171,7 +192,9 @@ private void ValidateUris()
171
192
public class ConnectionSettings : IEquatable < ConnectionSettings >
172
193
{
173
194
private readonly Address _address = new ( "amqp://localhost:5672" ) ;
174
- private readonly List < Address > _addresses = new ( ) ;
195
+ private readonly List < Uri > ? _uris ;
196
+ private readonly Dictionary < Uri , Address > ? _uriToAddress ;
197
+ private readonly IUriSelector _uriSelector = new RandomUriSelector ( ) ;
175
198
private readonly string _virtualHost = Consts . DefaultVirtualHost ;
176
199
private readonly string _containerId = string . Empty ;
177
200
private readonly uint _maxFrameSize = Consts . DefaultMaxFrameSize ;
@@ -197,7 +220,6 @@ public ConnectionSettings(Uri uri,
197
220
password : password ,
198
221
path : "/" ,
199
222
scheme : uri . Scheme ) ;
200
- _addresses . Add ( _address ) ;
201
223
202
224
if ( _address . UseSsl && _tlsSettings == null )
203
225
{
@@ -206,16 +228,27 @@ public ConnectionSettings(Uri uri,
206
228
}
207
229
208
230
public ConnectionSettings ( IEnumerable < Uri > uris ,
231
+ IUriSelector ? uriSelector = null ,
209
232
string ? containerId = null ,
210
233
SaslMechanism ? saslMechanism = null ,
211
234
IRecoveryConfiguration ? recoveryConfiguration = null ,
212
235
uint ? maxFrameSize = null ,
213
236
TlsSettings ? tlsSettings = null )
214
237
: this ( containerId , saslMechanism , recoveryConfiguration , maxFrameSize , tlsSettings )
215
238
{
239
+ _uris = uris . ToList ( ) ;
240
+
241
+ if ( uriSelector is not null )
242
+ {
243
+ _uriSelector = uriSelector ;
244
+ }
245
+
246
+ _uriToAddress = new ( _uris . Count ) ;
247
+
216
248
string ? tmpVirtualHost = null ;
217
249
218
- foreach ( Uri uri in uris )
250
+ bool first = true ;
251
+ foreach ( Uri uri in _uris )
219
252
{
220
253
( string ? user , string ? password ) = ProcessUserInfo ( uri ) ;
221
254
@@ -238,10 +271,15 @@ public ConnectionSettings(IEnumerable<Uri> uris,
238
271
password : password ,
239
272
path : "/" ,
240
273
scheme : uri . Scheme ) ;
241
- _addresses . Add ( address ) ;
242
- }
243
274
244
- _address = _addresses [ 0 ] ;
275
+ _uriToAddress [ uri ] = address ;
276
+
277
+ if ( first )
278
+ {
279
+ _address = address ;
280
+ first = false ;
281
+ }
282
+ }
245
283
246
284
if ( tmpVirtualHost is not null )
247
285
{
@@ -265,7 +303,6 @@ public ConnectionSettings(string scheme,
265
303
_address = new Address ( host : host , port : port ,
266
304
user : user , password : password ,
267
305
path : "/" , scheme : scheme ) ;
268
- _addresses . Add ( _address ) ;
269
306
270
307
if ( virtualHost is not null )
271
308
{
@@ -331,23 +368,34 @@ internal Address Address
331
368
{
332
369
get
333
370
{
334
- if ( _addresses . Count == 1 )
371
+ if ( _uris is not null &&
372
+ _uriSelector is not null &&
373
+ _uriToAddress is not null )
335
374
{
336
- if ( false == Object . ReferenceEquals ( _address , _addresses [ 0 ] ) )
337
- {
338
- InternalBugException . CreateAndThrow ( "_address must be same object as _addresses[0]" ) ;
339
- }
340
- return _address ;
375
+ Uri uri = _uriSelector . Select ( _uris ) ;
376
+ return _uriToAddress [ uri ] ;
341
377
}
342
378
else
343
379
{
344
- // Note: the max value for RandomNext is not inclusive
345
- return _addresses [ Utils . RandomNext ( 0 , _addresses . Count ) ] ;
380
+ return _address ;
346
381
}
347
382
}
348
383
}
349
384
350
- internal List < Address > Addresses => _addresses ;
385
+ internal List < Address > ? Addresses
386
+ {
387
+ get
388
+ {
389
+ if ( _uriToAddress is not null )
390
+ {
391
+ return _uriToAddress . Values . ToList ( ) ;
392
+ }
393
+ else
394
+ {
395
+ return null ;
396
+ }
397
+ }
398
+ }
351
399
352
400
public override string ToString ( )
353
401
{
0 commit comments