@@ -66,7 +66,7 @@ public class ReplicaSetStatus {
66
66
void start () {
67
67
_updater .start ();
68
68
}
69
-
69
+
70
70
boolean ready (){
71
71
return _setName != null ;
72
72
}
@@ -151,30 +151,45 @@ ServerAddress getASecondary(){
151
151
/**
152
152
* @return a good secondary or null if can't find one
153
153
*/
154
- ServerAddress getASecondary ( String tagKey , String tagValue ){
154
+ ServerAddress getASecondary ( String tagKey , String tagValue ) {
155
155
_checkClosed ();
156
+ return getASecondary (tagKey , tagValue , _all , _random );
157
+ }
158
+
159
+ /**
160
+ * This was extracted so we can test the logic from a unit test. This can't be
161
+ * tested from a standalone unit test until node is more decoupled from this class.
162
+ *
163
+ * @return a good secondary or null if can't find one
164
+ */
165
+ static ServerAddress getASecondary ( final String pTagKey ,
166
+ final String pTagValue ,
167
+ final List <Node > pNodes ,
168
+ final Random pRandom )
169
+ {
156
170
Node best = null ;
157
171
double badBeforeBest = 0 ;
158
172
159
- if (tagKey == null && tagValue != null || tagValue == null & tagKey != null )
173
+ if (pTagKey == null && pTagValue != null || pTagValue == null & pTagKey != null )
160
174
throw new IllegalArgumentException ( "Tag Key & Value must be consistent: both defined or not defined." );
161
175
162
- int start = _random .nextInt ( _all .size () );
176
+ int start = pRandom .nextInt ( pNodes .size () );
177
+
178
+ final int nodeCount = pNodes .size ();
163
179
164
180
double mybad = 0 ;
165
181
166
- for ( int i =0 ; i < _all . size () ; i ++ ){
167
- Node n = _all .get ( ( start + i ) % _all . size () );
182
+ for ( int i =0 ; i < nodeCount ; i ++ ){
183
+ Node n = pNodes .get ( ( start + i ) % nodeCount );
168
184
169
185
if ( ! n .secondary () ){
170
186
mybad ++;
171
187
continue ;
172
- } else if (tagKey != null && !n .checkTag ( tagKey , tagValue )){
188
+ } else if (pTagKey != null && !n .checkTag ( pTagKey , pTagValue )){
173
189
mybad ++;
174
190
continue ;
175
191
}
176
192
177
-
178
193
if ( best == null ){
179
194
best = n ;
180
195
badBeforeBest = mybad ;
@@ -183,10 +198,9 @@ ServerAddress getASecondary( String tagKey, String tagValue ){
183
198
}
184
199
185
200
float diff = best ._pingTime - n ._pingTime ;
186
- if ( diff > slaveAcceptableLatencyMS ||
187
- // this is a complex way to make sure we get a random distribution of slaves
188
- ( ( badBeforeBest - mybad ) / ( _all .size () - 1 ) ) > _random .nextDouble () )
189
- {
201
+
202
+ // this is a complex way to make sure we get a random distribution of slaves
203
+ if ( diff > slaveAcceptableLatencyMS || ( ( badBeforeBest - mybad ) / ( nodeCount - 1 ) ) > pRandom .nextDouble () ) {
190
204
best = n ;
191
205
badBeforeBest = mybad ;
192
206
mybad = 0 ;
@@ -196,6 +210,7 @@ ServerAddress getASecondary( String tagKey, String tagValue ){
196
210
197
211
if ( best == null )
198
212
return null ;
213
+
199
214
return best ._addr ;
200
215
}
201
216
@@ -209,6 +224,9 @@ boolean hasServerUp() {
209
224
return false ;
210
225
}
211
226
227
+ /**
228
+ * The replica set node object.
229
+ */
212
230
class Node {
213
231
214
232
Node ( ServerAddress addr ){
@@ -366,7 +384,7 @@ public void close() {
366
384
_port .close ();
367
385
_port = null ;
368
386
}
369
-
387
+
370
388
final ServerAddress _addr ;
371
389
final Set <String > _names = Collections .synchronizedSet ( new HashSet <String >() );
372
390
DBPort _port ; // we have our own port so we can set different socket options and don't have to owrry about the pool
0 commit comments