@@ -126,7 +126,7 @@ _mongoc_cluster_update_state (mongoc_cluster_t *cluster)
126
126
127
127
BSON_ASSERT (cluster );
128
128
129
- for (i = 0 ; i < MONGOC_CLUSTER_MAX_NODES ; i ++ ) {
129
+ for (i = 0 ; i < cluster -> nodes_len ; i ++ ) {
130
130
node = & cluster -> nodes [i ];
131
131
if (node -> stamp && !node -> stream ) {
132
132
down_nodes ++ ;
@@ -481,6 +481,7 @@ _mongoc_cluster_init (mongoc_cluster_t *cluster,
481
481
void * client )
482
482
{
483
483
const mongoc_host_list_t * hosts ;
484
+ const mongoc_host_list_t * host_iter ;
484
485
uint32_t sockettimeoutms = DEFAULT_SOCKET_TIMEOUT_MSEC ;
485
486
uint32_t i ;
486
487
const bson_t * b ;
@@ -528,7 +529,16 @@ _mongoc_cluster_init (mongoc_cluster_t *cluster,
528
529
cluster -> sec_latency_ms = bson_iter_int32 (& iter );
529
530
}
530
531
531
- for (i = 0 ; i < MONGOC_CLUSTER_MAX_NODES ; i ++ ) {
532
+ if (cluster -> mode == MONGOC_CLUSTER_DIRECT ) {
533
+ i = 1 ;
534
+ } else {
535
+ for (host_iter = hosts , i = 0 ; host_iter ; host_iter = host_iter -> next , i ++ ) {}
536
+ }
537
+
538
+ cluster -> nodes = bson_malloc (i * sizeof (* cluster -> nodes ));
539
+ cluster -> nodes_len = i ;
540
+
541
+ for (i = 0 ; i < cluster -> nodes_len ; i ++ ) {
532
542
_mongoc_cluster_node_init (& cluster -> nodes [i ]);
533
543
cluster -> nodes [i ].stamp = 0 ;
534
544
cluster -> nodes [i ].index = i ;
@@ -570,12 +580,14 @@ _mongoc_cluster_destroy (mongoc_cluster_t *cluster) /* INOUT */
570
580
571
581
mongoc_uri_destroy (cluster -> uri );
572
582
573
- for (i = 0 ; i < MONGOC_CLUSTER_MAX_NODES ; i ++ ) {
583
+ for (i = 0 ; i < cluster -> nodes_len ; i ++ ) {
574
584
if (cluster -> nodes [i ].stream ) {
575
585
_mongoc_cluster_node_destroy (& cluster -> nodes [i ]);
576
586
}
577
587
}
578
588
589
+ bson_free (cluster -> nodes );
590
+
579
591
bson_free (cluster -> replSet );
580
592
cluster -> replSet = NULL ;
581
593
@@ -616,30 +628,36 @@ _mongoc_cluster_select (mongoc_cluster_t *cluster,
616
628
const mongoc_read_prefs_t * read_prefs ,
617
629
bson_error_t * error )
618
630
{
619
- mongoc_cluster_node_t * nodes [ MONGOC_CLUSTER_MAX_NODES ] ;
631
+ mongoc_cluster_node_t * * nodes ;
620
632
mongoc_read_mode_t read_mode = MONGOC_READ_PRIMARY ;
621
- int scores [ MONGOC_CLUSTER_MAX_NODES ] ;
633
+ int * scores ;
622
634
int max_score = 0 ;
623
635
uint32_t count ;
624
636
uint32_t watermark ;
625
637
int32_t nearest = -1 ;
626
638
bool need_primary ;
627
639
bool need_secondary ;
628
640
unsigned i ;
641
+ mongoc_cluster_node_t * node = NULL ;
629
642
630
643
ENTRY ;
631
644
632
645
bson_return_val_if_fail (cluster , NULL );
633
646
bson_return_val_if_fail (rpcs , NULL );
634
647
bson_return_val_if_fail (rpcs_len , NULL );
635
- bson_return_val_if_fail (hint <= MONGOC_CLUSTER_MAX_NODES , NULL );
648
+ bson_return_val_if_fail (hint <= cluster -> nodes_len , NULL );
649
+
650
+ nodes = bson_malloc (sizeof (* nodes ) * cluster -> nodes_len );
651
+ scores = bson_malloc (sizeof (* scores ) * cluster -> nodes_len );
636
652
637
653
/*
638
654
* We can take a few short-cut's if we are not talking to a replica set.
639
655
*/
640
656
switch (cluster -> mode ) {
641
- case MONGOC_CLUSTER_DIRECT :
642
- RETURN (cluster -> nodes [0 ].stream ? & cluster -> nodes [0 ] : NULL );
657
+ case MONGOC_CLUSTER_DIRECT : {
658
+ node = (cluster -> nodes [0 ].stream ? & cluster -> nodes [0 ] : NULL );
659
+ goto CLEANUP ;
660
+ }
643
661
case MONGOC_CLUSTER_SHARDED_CLUSTER :
644
662
need_primary = false;
645
663
need_secondary = false;
@@ -690,9 +708,10 @@ _mongoc_cluster_select (mongoc_cluster_t *cluster,
690
708
* Build our list of nodes with established connections. Short circuit if
691
709
* we require a primary and we found one.
692
710
*/
693
- for (i = 0 ; i < MONGOC_CLUSTER_MAX_NODES ; i ++ ) {
711
+ for (i = 0 ; i < cluster -> nodes_len ; i ++ ) {
694
712
if (need_primary && cluster -> nodes [i ].primary ) {
695
- RETURN (& cluster -> nodes [i ]);
713
+ node = & cluster -> nodes [i ];
714
+ goto CLEANUP ;
696
715
} else if (need_secondary && cluster -> nodes [i ].primary ) {
697
716
nodes [i ] = NULL ;
698
717
} else {
@@ -708,7 +727,7 @@ _mongoc_cluster_select (mongoc_cluster_t *cluster,
708
727
MONGOC_ERROR_CLIENT ,
709
728
MONGOC_ERROR_CLIENT_NO_ACCEPTABLE_PEER ,
710
729
"Requested PRIMARY node is not available." );
711
- RETURN ( NULL ) ;
730
+ goto CLEANUP ;
712
731
}
713
732
714
733
/*
@@ -723,7 +742,8 @@ _mongoc_cluster_select (mongoc_cluster_t *cluster,
723
742
"Requested node (%u) is not available." ,
724
743
hint );
725
744
}
726
- RETURN (nodes [hint - 1 ]);
745
+ node = nodes [hint - 1 ];
746
+ goto CLEANUP ;
727
747
}
728
748
729
749
/*
@@ -743,7 +763,7 @@ _mongoc_cluster_select (mongoc_cluster_t *cluster,
743
763
744
764
count = 0 ;
745
765
746
- for (i = 0 ; i < MONGOC_CLUSTER_MAX_NODES ; i ++ ) {
766
+ for (i = 0 ; i < cluster -> nodes_len ; i ++ ) {
747
767
if (nodes [i ]) {
748
768
if (read_prefs ) {
749
769
int score = _mongoc_read_prefs_score (read_prefs , nodes [i ]);
@@ -765,7 +785,7 @@ _mongoc_cluster_select (mongoc_cluster_t *cluster,
765
785
* Filter nodes with score less than highest score.
766
786
*/
767
787
if (max_score ) {
768
- for (i = 0 ; i < MONGOC_CLUSTER_MAX_NODES ; i ++ ) {
788
+ for (i = 0 ; i < cluster -> nodes_len ; i ++ ) {
769
789
if (nodes [i ] && (scores [i ] < max_score )) {
770
790
nodes [i ] = NULL ;
771
791
count -- ;
@@ -779,7 +799,7 @@ _mongoc_cluster_select (mongoc_cluster_t *cluster,
779
799
#define IS_NEARER_THAN (n , msec ) \
780
800
((msec < 0 && (n)->ping_avg_msec >= 0) || ((n)->ping_avg_msec < msec))
781
801
782
- for (i = 0 ; i < MONGOC_CLUSTER_MAX_NODES ; i ++ ) {
802
+ for (i = 0 ; i < cluster -> nodes_len ; i ++ ) {
783
803
if (nodes [i ]) {
784
804
if (IS_NEARER_THAN (nodes [i ], nearest )) {
785
805
nearest = nodes [i ]-> ping_avg_msec ;
@@ -794,7 +814,7 @@ _mongoc_cluster_select (mongoc_cluster_t *cluster,
794
814
*/
795
815
if (nearest != -1 ) {
796
816
watermark = nearest + cluster -> sec_latency_ms ;
797
- for (i = 0 ; i < MONGOC_CLUSTER_MAX_NODES ; i ++ ) {
817
+ for (i = 0 ; i < cluster -> nodes_len ; i ++ ) {
798
818
if (nodes [i ]) {
799
819
if (nodes [i ]-> ping_avg_msec > (int32_t )watermark ) {
800
820
nodes [i ] = NULL ;
@@ -812,23 +832,29 @@ _mongoc_cluster_select (mongoc_cluster_t *cluster,
812
832
MONGOC_ERROR_CLIENT ,
813
833
MONGOC_ERROR_CLIENT_NO_ACCEPTABLE_PEER ,
814
834
"Failed to locate a suitable MongoDB node." );
815
- RETURN ( NULL ) ;
835
+ goto CLEANUP ;
816
836
}
817
837
818
838
/*
819
839
* Choose a cluster node within threshold at random.
820
840
*/
821
841
count = count ? rand () % count : count ;
822
- for (i = 0 ; i < MONGOC_CLUSTER_MAX_NODES ; i ++ ) {
842
+ for (i = 0 ; i < cluster -> nodes_len ; i ++ ) {
823
843
if (nodes [i ]) {
824
844
if (!count ) {
825
- RETURN (nodes [i ]);
845
+ node = nodes [i ];
846
+ goto CLEANUP ;
826
847
}
827
848
count -- ;
828
849
}
829
850
}
830
851
831
- RETURN (NULL );
852
+ CLEANUP :
853
+
854
+ bson_free (nodes );
855
+ bson_free (scores );
856
+
857
+ RETURN (node );
832
858
}
833
859
834
860
@@ -842,19 +868,24 @@ _mongoc_cluster_preselect (mongoc_cluster_t *cluster, /* IN */
842
868
mongoc_cluster_node_t * node ;
843
869
mongoc_rpc_t rpc = {{ 0 }};
844
870
int retry_count = 0 ;
871
+ bson_error_t scoped_error ;
845
872
846
873
BSON_ASSERT (cluster );
847
874
848
875
rpc .header .opcode = opcode ;
849
876
850
877
while (!(node = _mongoc_cluster_select (cluster , & rpc , 1 , 0 , write_concern ,
851
- read_prefs , error ))) {
878
+ read_prefs , & scoped_error ))) {
852
879
if ((retry_count ++ == MAX_RETRY_COUNT ) ||
853
880
!_mongoc_cluster_reconnect (cluster , error )) {
854
881
break ;
855
882
}
856
883
}
857
884
885
+ if (!node && error ) {
886
+ memcpy (error , & scoped_error , sizeof (scoped_error ));
887
+ }
888
+
858
889
return node ? (node -> index + 1 ) : 0 ;
859
890
}
860
891
@@ -1997,7 +2028,7 @@ _mongoc_cluster_reconnect_replica_set (mongoc_cluster_t *cluster,
1997
2028
const mongoc_host_list_t * hosts ;
1998
2029
const mongoc_host_list_t * iter ;
1999
2030
mongoc_cluster_node_t node ;
2000
- mongoc_cluster_node_t saved_nodes [ MONGOC_CLUSTER_MAX_NODES ] ;
2031
+ mongoc_cluster_node_t * saved_nodes ;
2001
2032
mongoc_host_list_t host ;
2002
2033
mongoc_stream_t * stream ;
2003
2034
mongoc_list_t * list ;
@@ -2006,20 +2037,23 @@ _mongoc_cluster_reconnect_replica_set (mongoc_cluster_t *cluster,
2006
2037
const char * replSet ;
2007
2038
int i ;
2008
2039
int j ;
2040
+ bool rval = false;
2009
2041
2010
2042
ENTRY ;
2011
2043
2012
2044
BSON_ASSERT (cluster );
2013
2045
BSON_ASSERT (cluster -> mode == MONGOC_CLUSTER_REPLICA_SET );
2014
2046
2047
+ saved_nodes = bson_malloc0 (cluster -> nodes_len * sizeof (* saved_nodes ));
2048
+
2015
2049
MONGOC_DEBUG ("Reconnecting to replica set." );
2016
2050
2017
2051
if (!(hosts = mongoc_uri_get_hosts (cluster -> uri ))) {
2018
2052
bson_set_error (error ,
2019
2053
MONGOC_ERROR_CLIENT ,
2020
2054
MONGOC_ERROR_CLIENT_NOT_READY ,
2021
2055
"Invalid host list supplied." );
2022
- RETURN (false) ;
2056
+ goto CLEANUP ;
2023
2057
}
2024
2058
2025
2059
replSet = mongoc_uri_get_replica_set (cluster -> uri );
@@ -2098,9 +2132,7 @@ _mongoc_cluster_reconnect_replica_set (mongoc_cluster_t *cluster,
2098
2132
* we don't waste time doing that again.
2099
2133
*/
2100
2134
2101
- memset (saved_nodes , 0 , sizeof saved_nodes );
2102
-
2103
- for (i = 0 ; i < MONGOC_CLUSTER_MAX_NODES ; i ++ ) {
2135
+ for (i = 0 ; i < cluster -> nodes_len ; i ++ ) {
2104
2136
if (cluster -> nodes [i ].stream ) {
2105
2137
saved_nodes [i ].host = cluster -> nodes [i ].host ;
2106
2138
saved_nodes [i ].stream = cluster -> nodes [i ].stream ;
@@ -2109,7 +2141,7 @@ _mongoc_cluster_reconnect_replica_set (mongoc_cluster_t *cluster,
2109
2141
}
2110
2142
2111
2143
for (liter = list , i = 0 ;
2112
- liter && (i < MONGOC_CLUSTER_MAX_NODES );
2144
+ liter && (i < cluster -> nodes_len );
2113
2145
liter = liter -> next ) {
2114
2146
2115
2147
if (!_mongoc_host_list_from_string (& host , liter -> data )) {
@@ -2120,7 +2152,7 @@ _mongoc_cluster_reconnect_replica_set (mongoc_cluster_t *cluster,
2120
2152
2121
2153
stream = NULL ;
2122
2154
2123
- for (j = 0 ; j < MONGOC_CLUSTER_MAX_NODES ; j ++ ) {
2155
+ for (j = 0 ; j < cluster -> nodes_len ; j ++ ) {
2124
2156
if (0 == strcmp (saved_nodes [j ].host .host_and_port ,
2125
2157
host .host_and_port )) {
2126
2158
stream = saved_nodes [j ].stream ;
@@ -2162,7 +2194,7 @@ _mongoc_cluster_reconnect_replica_set (mongoc_cluster_t *cluster,
2162
2194
if (cluster -> nodes [i ].needs_auth ) {
2163
2195
if (!_mongoc_cluster_auth_node (cluster , & cluster -> nodes [i ], error )) {
2164
2196
_mongoc_cluster_node_destroy (& cluster -> nodes [i ]);
2165
- RETURN (false) ;
2197
+ goto CLEANUP ;
2166
2198
}
2167
2199
cluster -> nodes [i ].needs_auth = false;
2168
2200
}
@@ -2188,7 +2220,7 @@ _mongoc_cluster_reconnect_replica_set (mongoc_cluster_t *cluster,
2188
2220
* Cleanup all potential saved connections that were not used.
2189
2221
*/
2190
2222
2191
- for (j = 0 ; j < MONGOC_CLUSTER_MAX_NODES ; j ++ ) {
2223
+ for (j = 0 ; j < cluster -> nodes_len ; j ++ ) {
2192
2224
if (saved_nodes [j ].stream ) {
2193
2225
mongoc_stream_destroy (saved_nodes [j ].stream );
2194
2226
saved_nodes [j ].stream = NULL ;
@@ -2200,12 +2232,18 @@ _mongoc_cluster_reconnect_replica_set (mongoc_cluster_t *cluster,
2200
2232
MONGOC_ERROR_CLIENT ,
2201
2233
MONGOC_ERROR_CLIENT_NO_ACCEPTABLE_PEER ,
2202
2234
"No acceptable peer could be found." );
2203
- RETURN (false) ;
2235
+ goto CLEANUP ;
2204
2236
}
2205
2237
2206
2238
_mongoc_cluster_update_state (cluster );
2207
2239
2208
- RETURN (true);
2240
+ rval = true;
2241
+
2242
+ CLEANUP :
2243
+
2244
+ bson_free (saved_nodes );
2245
+
2246
+ RETURN (rval );
2209
2247
}
2210
2248
2211
2249
@@ -2360,7 +2398,7 @@ _mongoc_cluster_reconnect (mongoc_cluster_t *cluster,
2360
2398
*
2361
2399
* TODO: We could be better about reusing connections.
2362
2400
*/
2363
- for (i = 0 ; i < MONGOC_CLUSTER_MAX_NODES ; i ++ ) {
2401
+ for (i = 0 ; i < cluster -> nodes_len ; i ++ ) {
2364
2402
if (cluster -> nodes [i ].stream ) {
2365
2403
mongoc_stream_close (cluster -> nodes [i ].stream );
2366
2404
mongoc_stream_destroy (cluster -> nodes [i ].stream );
@@ -2415,7 +2453,7 @@ _mongoc_cluster_command_early (mongoc_cluster_t *cluster,
2415
2453
2416
2454
node = _mongoc_cluster_get_primary (cluster );
2417
2455
2418
- for (i = 0 ; !node && i < MONGOC_CLUSTER_MAX_NODES ; i ++ ) {
2456
+ for (i = 0 ; !node && i < cluster -> nodes_len ; i ++ ) {
2419
2457
if (cluster -> nodes [i ].stream ) {
2420
2458
node = & cluster -> nodes [i ];
2421
2459
}
@@ -2902,7 +2940,7 @@ _mongoc_cluster_try_recv (mongoc_cluster_t *cluster,
2902
2940
bson_return_val_if_fail (rpc , false);
2903
2941
bson_return_val_if_fail (buffer , false);
2904
2942
bson_return_val_if_fail (hint , false);
2905
- bson_return_val_if_fail (hint <= MONGOC_CLUSTER_MAX_NODES , false);
2943
+ bson_return_val_if_fail (hint <= cluster -> nodes_len , false);
2906
2944
2907
2945
/*
2908
2946
* Fetch the node to communicate over.
@@ -2996,7 +3034,7 @@ _mongoc_cluster_stamp (const mongoc_cluster_t *cluster,
2996
3034
{
2997
3035
bson_return_val_if_fail (cluster , 0 );
2998
3036
bson_return_val_if_fail (node > 0 , 0 );
2999
- bson_return_val_if_fail (node <= MONGOC_CLUSTER_MAX_NODES , 0 );
3037
+ bson_return_val_if_fail (node <= cluster -> nodes_len , 0 );
3000
3038
3001
3039
return cluster -> nodes [node ].stamp ;
3002
3040
}
@@ -3017,7 +3055,7 @@ _mongoc_cluster_get_primary (mongoc_cluster_t *cluster)
3017
3055
3018
3056
BSON_ASSERT (cluster );
3019
3057
3020
- for (i = 0 ; i < MONGOC_CLUSTER_MAX_NODES ; i ++ ) {
3058
+ for (i = 0 ; i < cluster -> nodes_len ; i ++ ) {
3021
3059
if (cluster -> nodes [i ].primary ) {
3022
3060
return & cluster -> nodes [i ];
3023
3061
}
0 commit comments