@@ -1077,6 +1077,9 @@ _mongoc_cluster_ismaster (mongoc_cluster_t *cluster,
10771077 bson_free (node -> replSet );
10781078 node -> replSet = NULL ;
10791079
1080+ bson_destroy (& node -> tags );
1081+ bson_init (& node -> tags );
1082+
10801083 if (bson_iter_init_find_case (& iter , & reply , "isMaster" ) &&
10811084 BSON_ITER_HOLDS_BOOL (& iter ) &&
10821085 bson_iter_bool (& iter )) {
@@ -2067,6 +2070,95 @@ host_list_destroy (mongoc_host_list_t *hl)
20672070}
20682071
20692072
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+
20702162/*
20712163 *--------------------------------------------------------------------------
20722164 *
@@ -2098,26 +2190,23 @@ _mongoc_cluster_reconnect_replica_set (mongoc_cluster_t *cluster,
20982190 const mongoc_host_list_t * iter ;
20992191 mongoc_host_list_t * failed_hosts = NULL ;
21002192 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 ;
21032196 mongoc_host_list_t host ;
21042197 mongoc_stream_t * stream ;
2105- mongoc_list_t * list ;
2198+ mongoc_list_t * list = NULL ;
21062199 mongoc_list_t * liter ;
21072200 int32_t ping ;
21082201 const char * replSet ;
21092202 uint32_t i ;
2110- uint32_t j ;
21112203 bool rval = false;
21122204
21132205 ENTRY ;
21142206
21152207 BSON_ASSERT (cluster );
21162208 BSON_ASSERT (cluster -> mode == MONGOC_CLUSTER_REPLICA_SET );
21172209
2118- saved_nodes = bson_malloc0 (cluster -> nodes_len * sizeof (* saved_nodes ));
2119- saved_nodes_len = cluster -> nodes_len ;
2120-
21212210 MONGOC_DEBUG ("Reconnecting to replica set." );
21222211
21232212 if (!(hosts = mongoc_uri_get_hosts (cluster -> uri ))) {
@@ -2135,26 +2224,18 @@ _mongoc_cluster_reconnect_replica_set (mongoc_cluster_t *cluster,
21352224 * Replica Set (Re)Connection Strategy
21362225 * ===================================
21372226 *
2138- * First we break all existing connections. This may change .
2227+ * First we save existing connections.
21392228 *
21402229 * To perform the replica set connection, we connect to each of the
21412230 * pre-configured replicaSet nodes. (There may in fact only be one).
21422231 *
2143- * TODO: We should perform this initial connection in parallel.
2144- *
21452232 * 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.
21502235 *
21512236 * We return true if any of the connections were successful, however
21522237 * we must update the cluster health appropriately so that callers
21532238 * 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.
21582239 */
21592240
21602241 cluster -> last_reconnect = bson_get_monotonic_time ();
@@ -2202,28 +2283,18 @@ _mongoc_cluster_reconnect_replica_set (mongoc_cluster_t *cluster,
22022283
22032284 /*
22042285 * 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.
22072287 */
22082288
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 );
22162291
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 );
22212293
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 ;
22272298
22282299 for (liter = list , i = 0 ; liter ; liter = liter -> next ) {
22292300 if (!_mongoc_host_list_from_string (& host , liter -> data )) {
@@ -2237,15 +2308,10 @@ _mongoc_cluster_reconnect_replica_set (mongoc_cluster_t *cluster,
22372308 continue ;
22382309 }
22392310
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 );
22492315
22502316 if (!stream ) {
22512317 stream = _mongoc_client_create_stream (cluster -> client , & host , error );
@@ -2300,20 +2366,6 @@ _mongoc_cluster_reconnect_replica_set (mongoc_cluster_t *cluster,
23002366 cluster -> nodes_len = i ;
23012367 }
23022368
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-
23172369 if (i == 0 ) {
23182370 bson_set_error (error ,
23192371 MONGOC_ERROR_CLIENT ,
@@ -2328,8 +2380,12 @@ _mongoc_cluster_reconnect_replica_set (mongoc_cluster_t *cluster,
23282380
23292381CLEANUP :
23302382
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+ }
23322387
2388+ destroy_nodes_list (& saved_nodes , saved_nodes_len );
23332389 host_list_destroy (failed_hosts );
23342390
23352391 RETURN (rval );
0 commit comments