@@ -29,8 +29,6 @@ internal class ConnectedInstanceCollection
29
29
{
30
30
// private fields
31
31
private readonly object _connectedInstancesLock = new object ( ) ;
32
- private readonly Random _random = new Random ( ) ;
33
- private readonly object _randomLock = new object ( ) ;
34
32
35
33
private Dictionary < MongoServerInstance , LinkedListNode < InstanceWithPingTime > > _instanceLookup ;
36
34
private LinkedList < InstanceWithPingTime > _instances ;
@@ -59,99 +57,29 @@ public void Clear()
59
57
}
60
58
61
59
/// <summary>
62
- /// Gets the primary instance.
63
- /// </summary>
64
- /// <returns>The primary instance (or null if there is none).</returns>
65
- public MongoServerInstance GetPrimary ( )
66
- {
67
- lock ( _connectedInstancesLock )
68
- {
69
- return _instances . Select ( x => x . Instance ) . Where ( i => i . IsPrimary ) . FirstOrDefault ( ) ;
70
- }
71
- }
72
-
73
- /// <summary>
74
- /// Gets a randomly selected matching instance.
60
+ /// Gets a list of InstanceWithPingTimes.
75
61
/// </summary>
76
- /// <param name="readPreference">The read preference must be matched.</param>
77
- /// <param name="secondaryAcceptableLatency">The maximum acceptable secondary latency.</param>
78
- /// <returns>A randomly selected matching instance.</returns>
79
- public MongoServerInstance GetRandomInstance ( ReadPreference readPreference , TimeSpan secondaryAcceptableLatency )
62
+ /// <returns>The list of InstanceWithPingTimes</returns>
63
+ public List < InstanceWithPingTime > GetInstancesWithPingTime ( )
80
64
{
81
65
lock ( _connectedInstancesLock )
82
66
{
83
- var matchingInstances = new List < MongoServerInstance > ( ) ;
84
- var maxPingTime = TimeSpan . MaxValue ;
85
-
86
- var tagSets = readPreference . TagSets ?? new ReplicaSetTagSet [ ] { new ReplicaSetTagSet ( ) } ;
87
- foreach ( var tagSet in tagSets )
88
- {
89
- foreach ( var instanceWithPingTime in _instances )
90
- {
91
- if ( instanceWithPingTime . CachedAveragePingTime > maxPingTime )
92
- {
93
- break ; // the rest will exceed maxPingTime also
94
- }
95
-
96
- var instance = instanceWithPingTime . Instance ;
97
- if ( instance . IsSecondary || instance . IsPrimary && readPreference . ReadPreferenceMode == ReadPreferenceMode . Nearest )
98
- {
99
- if ( tagSet . MatchesInstance ( instance ) )
100
- {
101
- matchingInstances . Add ( instance ) ;
102
- if ( maxPingTime == TimeSpan . MaxValue )
103
- {
104
- maxPingTime = instanceWithPingTime . CachedAveragePingTime + secondaryAcceptableLatency ;
105
- }
106
- }
107
- }
108
- }
109
-
110
- if ( matchingInstances . Count != 0 )
111
- {
112
- var n = _random . Next ( matchingInstances . Count ) ;
113
- return matchingInstances [ n ] ; // randomly selected matching instance
114
- }
115
- }
116
-
117
- return null ;
67
+ // note: make copies of InstanceWithPingTime values because they can change after we return
68
+ return _instances
69
+ . Select ( x => new InstanceWithPingTime { Instance = x . Instance , CachedAveragePingTime = x . CachedAveragePingTime } )
70
+ . ToList ( ) ;
118
71
}
119
72
}
120
73
121
74
/// <summary>
122
- /// Gets a randomly selected matching instance.
75
+ /// Gets the primary instance.
123
76
/// </summary>
124
- /// <param name="secondaryAcceptableLatency">The maximum acceptable secondary latency.</param>
125
- /// <returns>A randomly selected matching instance.</returns>
126
- public MongoServerInstance GetRandomInstance ( TimeSpan secondaryAcceptableLatency )
77
+ /// <returns>The primary instance (or null if there is none).</returns>
78
+ public MongoServerInstance GetPrimary ( )
127
79
{
128
80
lock ( _connectedInstancesLock )
129
81
{
130
- var matchingInstances = new List < MongoServerInstance > ( ) ;
131
- var maxPingTime = TimeSpan . MaxValue ;
132
-
133
- foreach ( var instanceWithPingTime in _instances )
134
- {
135
- if ( instanceWithPingTime . CachedAveragePingTime > maxPingTime )
136
- {
137
- break ; // the rest will exceed maxPingTime also
138
- }
139
-
140
- var instance = instanceWithPingTime . Instance ;
141
- matchingInstances . Add ( instance ) ;
142
- if ( maxPingTime == TimeSpan . MaxValue )
143
- {
144
- maxPingTime = instanceWithPingTime . CachedAveragePingTime + secondaryAcceptableLatency ;
145
- }
146
- }
147
-
148
- if ( matchingInstances . Count != 0 )
149
- {
150
- var n = _random . Next ( matchingInstances . Count ) ;
151
- return matchingInstances [ n ] ; // randomly selected matching instance
152
- }
153
-
154
- return null ;
82
+ return _instances . Select ( x => x . Instance ) . FirstOrDefault ( i => i . IsPrimary ) ;
155
83
}
156
84
}
157
85
@@ -272,7 +200,7 @@ private void InstanceAveragePingTimeChanged(object sender, EventArgs e)
272
200
273
201
// When dealing with an always sorted linked list, we need to maintain a cached version of the ping time
274
202
// to compare against because a MongoServerInstance's could change on it's own making the sorting of the list incorrect.
275
- private class InstanceWithPingTime
203
+ internal class InstanceWithPingTime
276
204
{
277
205
public MongoServerInstance Instance ;
278
206
public TimeSpan CachedAveragePingTime ;
0 commit comments