@@ -1077,6 +1077,9 @@ _mongoc_cluster_ismaster (mongoc_cluster_t *cluster,
1077
1077
bson_free (node -> replSet );
1078
1078
node -> replSet = NULL ;
1079
1079
1080
+ bson_destroy (& node -> tags );
1081
+ bson_init (& node -> tags );
1082
+
1080
1083
if (bson_iter_init_find_case (& iter , & reply , "isMaster" ) &&
1081
1084
BSON_ITER_HOLDS_BOOL (& iter ) &&
1082
1085
bson_iter_bool (& iter )) {
@@ -2067,6 +2070,95 @@ host_list_destroy (mongoc_host_list_t *hl)
2067
2070
}
2068
2071
2069
2072
2073
+ static uint32_t
2074
+ list_len (const mongoc_list_t * list )
2075
+ {
2076
+ const mongoc_list_t * liter ;
2077
+ uint32_t i ;
2078
+
2079
+ for (liter = list , i = 0 ; liter ; liter = liter -> next , i ++ ) {}
2080
+
2081
+ return i ;
2082
+ }
2083
+
2084
+
2085
+ static mongoc_cluster_node_t *
2086
+ save_nodes (mongoc_cluster_node_t * nodes ,
2087
+ size_t nodes_len )
2088
+ {
2089
+ mongoc_cluster_node_t * saved_nodes ;
2090
+ int i ;
2091
+
2092
+ saved_nodes = bson_malloc0 (nodes_len * sizeof (mongoc_cluster_node_t ));
2093
+
2094
+ for (i = 0 ; i < nodes_len ; i ++ ) {
2095
+ _mongoc_cluster_node_init (& saved_nodes [i ]);
2096
+ if (nodes [i ].stream ) {
2097
+ saved_nodes [i ].host = nodes [i ].host ;
2098
+ saved_nodes [i ].stream = nodes [i ].stream ;
2099
+ nodes [i ].stream = NULL ;
2100
+ }
2101
+ }
2102
+
2103
+ return saved_nodes ;
2104
+ }
2105
+
2106
+
2107
+
2108
+ static mongoc_cluster_node_t *
2109
+ nodes_list_new (size_t nodes_len )
2110
+ {
2111
+ mongoc_cluster_node_t * nodes ;
2112
+ size_t i ;
2113
+
2114
+ nodes = bson_malloc0 (sizeof (mongoc_cluster_node_t ) * nodes_len );
2115
+ for (i = 0 ; i < nodes_len ; i ++ ) {
2116
+ _mongoc_cluster_node_init (& nodes [i ]);
2117
+ /* guard against counter errors, see CDRIVER-695 */
2118
+ nodes [i ].valid = false;
2119
+ }
2120
+
2121
+ return nodes ;
2122
+ }
2123
+
2124
+
2125
+ static mongoc_stream_t *
2126
+ restore_stream (mongoc_cluster_node_t * saved_nodes ,
2127
+ size_t saved_nodes_len ,
2128
+ char * host_and_port )
2129
+ {
2130
+ size_t i ;
2131
+ mongoc_stream_t * stream ;
2132
+
2133
+ for (i = 0 ; i < saved_nodes_len ; i ++ ) {
2134
+ if (0 == strcmp (saved_nodes [i ].host .host_and_port ,
2135
+ host_and_port )) {
2136
+ stream = saved_nodes [i ].stream ;
2137
+ saved_nodes [i ].stream = NULL ;
2138
+ return stream ;
2139
+ }
2140
+ }
2141
+
2142
+ return NULL ;
2143
+ }
2144
+
2145
+
2146
+ static void
2147
+ destroy_nodes_list (mongoc_cluster_node_t * * nodes_ptr ,
2148
+ size_t nodes_len )
2149
+ {
2150
+ mongoc_cluster_node_t * nodes = * nodes_ptr ;
2151
+ size_t i ;
2152
+
2153
+ for (i = 0 ; i < nodes_len ; i ++ ) {
2154
+ _mongoc_cluster_node_destroy (& nodes [i ]);
2155
+ }
2156
+
2157
+ bson_free (nodes );
2158
+ * nodes_ptr = NULL ;
2159
+ }
2160
+
2161
+
2070
2162
/*
2071
2163
*--------------------------------------------------------------------------
2072
2164
*
@@ -2098,26 +2190,23 @@ _mongoc_cluster_reconnect_replica_set (mongoc_cluster_t *cluster,
2098
2190
const mongoc_host_list_t * iter ;
2099
2191
mongoc_host_list_t * failed_hosts = NULL ;
2100
2192
mongoc_cluster_node_t node ;
2101
- mongoc_cluster_node_t * saved_nodes ;
2102
- size_t saved_nodes_len ;
2193
+ mongoc_cluster_node_t * saved_nodes = NULL ;
2194
+ size_t saved_nodes_len = 0 ;
2195
+ uint32_t peers_len ;
2103
2196
mongoc_host_list_t host ;
2104
2197
mongoc_stream_t * stream ;
2105
- mongoc_list_t * list ;
2198
+ mongoc_list_t * list = NULL ;
2106
2199
mongoc_list_t * liter ;
2107
2200
int32_t ping ;
2108
2201
const char * replSet ;
2109
2202
uint32_t i ;
2110
- uint32_t j ;
2111
2203
bool rval = false;
2112
2204
2113
2205
ENTRY ;
2114
2206
2115
2207
BSON_ASSERT (cluster );
2116
2208
BSON_ASSERT (cluster -> mode == MONGOC_CLUSTER_REPLICA_SET );
2117
2209
2118
- saved_nodes = bson_malloc0 (cluster -> nodes_len * sizeof (* saved_nodes ));
2119
- saved_nodes_len = cluster -> nodes_len ;
2120
-
2121
2210
MONGOC_DEBUG ("Reconnecting to replica set." );
2122
2211
2123
2212
if (!(hosts = mongoc_uri_get_hosts (cluster -> uri ))) {
@@ -2135,26 +2224,18 @@ _mongoc_cluster_reconnect_replica_set (mongoc_cluster_t *cluster,
2135
2224
* Replica Set (Re)Connection Strategy
2136
2225
* ===================================
2137
2226
*
2138
- * First we break all existing connections. This may change .
2227
+ * First we save existing connections.
2139
2228
*
2140
2229
* To perform the replica set connection, we connect to each of the
2141
2230
* pre-configured replicaSet nodes. (There may in fact only be one).
2142
2231
*
2143
- * TODO: We should perform this initial connection in parallel.
2144
- *
2145
2232
* Using the result of an "isMaster" on each of these nodes, we can
2146
- * prime the cluster nodes we want to connect to.
2147
- *
2148
- * We then connect to all of these nodes in parallel. Once we have
2149
- * all of the working nodes established, we can complete the process.
2233
+ * prime the cluster nodes we want to connect to. Then we connect to
2234
+ * them.
2150
2235
*
2151
2236
* We return true if any of the connections were successful, however
2152
2237
* we must update the cluster health appropriately so that callers
2153
2238
* that need a PRIMARY node can force reconnection.
2154
- *
2155
- * TODO: At some point in the future, we will need to authenticate
2156
- * before calling an "isMaster". But that is dependent on a
2157
- * few server "features" first.
2158
2239
*/
2159
2240
2160
2241
cluster -> last_reconnect = bson_get_monotonic_time ();
@@ -2202,28 +2283,18 @@ _mongoc_cluster_reconnect_replica_set (mongoc_cluster_t *cluster,
2202
2283
2203
2284
/*
2204
2285
* To avoid reconnecting to all of the peers, we will save the
2205
- * functional connections (and save their ping times) so that
2206
- * we don't waste time doing that again.
2286
+ * functional connections.
2207
2287
*/
2208
2288
2209
- for (i = 0 ; i < cluster -> nodes_len ; i ++ ) {
2210
- if (cluster -> nodes [i ].stream ) {
2211
- saved_nodes [i ].host = cluster -> nodes [i ].host ;
2212
- saved_nodes [i ].stream = cluster -> nodes [i ].stream ;
2213
- cluster -> nodes [i ].stream = NULL ;
2214
- }
2215
- }
2289
+ saved_nodes_len = cluster -> nodes_len ;
2290
+ saved_nodes = save_nodes (cluster -> nodes , cluster -> nodes_len );
2216
2291
2217
- /* reinitialize nodes with same length as peer list. */
2218
- for (liter = list , i = 0 ; liter ; liter = liter -> next , i ++ ) {}
2219
- cluster -> nodes = bson_realloc (cluster -> nodes , sizeof (* cluster -> nodes ) * i );
2220
- cluster -> nodes_len = i ;
2292
+ destroy_nodes_list (& cluster -> nodes , cluster -> nodes_len );
2221
2293
2222
- for (j = 0 ; j < i ; j ++ ) {
2223
- _mongoc_cluster_node_init (& cluster -> nodes [j ]);
2224
- /* guard against counter errors, see CDRIVER-695 */
2225
- cluster -> nodes [j ].valid = false;
2226
- }
2294
+ /* reinitialize nodes with same length as peer list. */
2295
+ peers_len = list_len (list );
2296
+ cluster -> nodes = nodes_list_new (peers_len );
2297
+ cluster -> nodes_len = peers_len ;
2227
2298
2228
2299
for (liter = list , i = 0 ; liter ; liter = liter -> next ) {
2229
2300
if (!_mongoc_host_list_from_string (& host , liter -> data )) {
@@ -2237,15 +2308,10 @@ _mongoc_cluster_reconnect_replica_set (mongoc_cluster_t *cluster,
2237
2308
continue ;
2238
2309
}
2239
2310
2240
- stream = NULL ;
2241
-
2242
- for (j = 0 ; j < saved_nodes_len ; j ++ ) {
2243
- if (0 == strcmp (saved_nodes [j ].host .host_and_port ,
2244
- host .host_and_port )) {
2245
- stream = saved_nodes [j ].stream ;
2246
- saved_nodes [j ].stream = NULL ;
2247
- }
2248
- }
2311
+ /* NULLs the saved node's stream if found and returns it */
2312
+ stream = restore_stream (saved_nodes ,
2313
+ saved_nodes_len ,
2314
+ host .host_and_port );
2249
2315
2250
2316
if (!stream ) {
2251
2317
stream = _mongoc_client_create_stream (cluster -> client , & host , error );
@@ -2300,20 +2366,6 @@ _mongoc_cluster_reconnect_replica_set (mongoc_cluster_t *cluster,
2300
2366
cluster -> nodes_len = i ;
2301
2367
}
2302
2368
2303
- _mongoc_list_foreach (list , (void (* )(void * ,void * ))bson_free , NULL );
2304
- _mongoc_list_destroy (list );
2305
-
2306
- /*
2307
- * Cleanup all potential saved connections that were not used.
2308
- */
2309
-
2310
- for (j = 0 ; j < saved_nodes_len ; j ++ ) {
2311
- if (saved_nodes [j ].stream ) {
2312
- mongoc_stream_destroy (saved_nodes [j ].stream );
2313
- saved_nodes [j ].stream = NULL ;
2314
- }
2315
- }
2316
-
2317
2369
if (i == 0 ) {
2318
2370
bson_set_error (error ,
2319
2371
MONGOC_ERROR_CLIENT ,
@@ -2328,8 +2380,12 @@ _mongoc_cluster_reconnect_replica_set (mongoc_cluster_t *cluster,
2328
2380
2329
2381
CLEANUP :
2330
2382
2331
- bson_free (saved_nodes );
2383
+ if (list ) {
2384
+ _mongoc_list_foreach (list , (void (* ) (void * , void * )) bson_free , NULL );
2385
+ _mongoc_list_destroy (list );
2386
+ }
2332
2387
2388
+ destroy_nodes_list (& saved_nodes , saved_nodes_len );
2333
2389
host_list_destroy (failed_hosts );
2334
2390
2335
2391
RETURN (rval );
0 commit comments