Skip to content

Commit 2946e34

Browse files
committed
CDRIVER-3808 fix srv polling thread from spinning (#692)
If an SRV URI is used to connect to a deployment other than a sharded cluster the SRV polling thread spins since it bypasses the poll due to the topology type being ineligible. This change terminates the thread when the topology type is discovered to be ineligible.
1 parent 57b2b94 commit 2946e34

File tree

3 files changed

+57
-17
lines changed

3 files changed

+57
-17
lines changed

src/libmongoc/src/mongoc/mongoc-topology-background-monitoring.c

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,12 @@ static BSON_THREAD_FUN (srv_polling_run, topology_void)
4848
}
4949

5050
/* This will check if a scan is due. */
51+
if (!mongoc_topology_should_rescan_srv (topology)) {
52+
TRACE ("%s\n", "topology ineligible for SRV polling, stopping");
53+
bson_mutex_unlock (&topology->mutex);
54+
break;
55+
}
56+
5157
mongoc_topology_rescan_srv (topology);
5258

5359
/* Unlock and sleep until next scan is due, or until shutdown signalled.
@@ -142,7 +148,8 @@ _mongoc_topology_background_monitoring_start (mongoc_topology_t *topology)
142148
/* Reconcile to create the first server monitors. */
143149
_mongoc_topology_background_monitoring_reconcile (topology);
144150
/* Start SRV polling thread. */
145-
if (mongoc_uri_get_service (topology->uri)) {
151+
if (mongoc_topology_should_rescan_srv (topology)) {
152+
topology->is_srv_polling = true;
146153
COMMON_PREFIX (thread_create)
147154
(&topology->srv_polling_thread, srv_polling_run, topology);
148155
}
@@ -270,7 +277,6 @@ _mongoc_topology_background_monitoring_stop (mongoc_topology_t *topology)
270277
{
271278
mongoc_server_monitor_t *server_monitor;
272279
int i;
273-
bool is_srv_polling;
274280

275281
BSON_ASSERT (!topology->single_threaded);
276282

@@ -281,9 +287,8 @@ _mongoc_topology_background_monitoring_stop (mongoc_topology_t *topology)
281287
topology->scanner_state = MONGOC_TOPOLOGY_SCANNER_SHUTTING_DOWN;
282288
TRACE ("%s", "background monitoring stopping");
283289

284-
is_srv_polling = NULL != mongoc_uri_get_service (topology->uri);
285290
/* Signal SRV polling to shut down (if it is started). */
286-
if (is_srv_polling) {
291+
if (topology->is_srv_polling) {
287292
mongoc_cond_signal (&topology->srv_polling_cond);
288293
}
289294

@@ -320,7 +325,7 @@ _mongoc_topology_background_monitoring_stop (mongoc_topology_t *topology)
320325
}
321326

322327
/* Wait for SRV polling thread. */
323-
if (is_srv_polling) {
328+
if (topology->is_srv_polling) {
324329
COMMON_PREFIX (thread_join) (topology->srv_polling_thread);
325330
}
326331

src/libmongoc/src/mongoc/mongoc-topology-private.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ typedef struct _mongoc_topology_t {
8484

8585
/* Is client side encryption enabled? */
8686
bool cse_enabled;
87+
bool is_srv_polling;
8788

8889
#ifdef MONGOC_ENABLE_CLIENT_SIDE_ENCRYPTION
8990
_mongoc_crypt_t *crypt;
@@ -225,4 +226,7 @@ _mongoc_topology_clear_connection_pool (mongoc_topology_t *topology,
225226

226227
void
227228
mongoc_topology_rescan_srv (mongoc_topology_t *topology);
229+
230+
bool
231+
mongoc_topology_should_rescan_srv (mongoc_topology_t *topology);
228232
#endif

src/libmongoc/src/mongoc/mongoc-topology.c

Lines changed: 43 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -613,12 +613,50 @@ mongoc_topology_apply_scanned_srv_hosts (mongoc_uri_t *uri,
613613
return had_valid_hosts;
614614
}
615615

616+
/*
617+
*--------------------------------------------------------------------------
618+
*
619+
* mongoc_topology_should_rescan_srv --
620+
*
621+
* Checks whether it is valid to rescan SRV records on the topology.
622+
* Namely, that the topology type is Sharded or Unknown, and that
623+
* the topology URI was configured with SRV.
624+
*
625+
* If this returns false, caller can stop scanning SRV records
626+
* and does not need to try again in the future.
627+
*
628+
* NOTE: this method expects @topology's mutex to be locked on entry.
629+
*
630+
* --------------------------------------------------------------------------
631+
*/
632+
bool
633+
mongoc_topology_should_rescan_srv (mongoc_topology_t *topology) {
634+
const char *service;
635+
636+
service = mongoc_uri_get_service (topology->uri);
637+
if (!service) {
638+
/* Only rescan if we have a mongodb+srv:// URI. */
639+
return false;
640+
}
641+
642+
if ((topology->description.type != MONGOC_TOPOLOGY_SHARDED) &&
643+
(topology->description.type != MONGOC_TOPOLOGY_UNKNOWN)) {
644+
/* Only perform rescan for sharded topology. */
645+
return false;
646+
}
647+
648+
return true;
649+
}
650+
616651
/*
617652
*--------------------------------------------------------------------------
618653
*
619654
* mongoc_topology_rescan_srv --
620655
*
621656
* Queries SRV records for new hosts in a mongos cluster.
657+
* Caller must call mongoc_topology_should_rescan_srv before calling
658+
* to ensure preconditions are met (while holding @topology's mutex
659+
* for the duration of both calls).
622660
*
623661
* NOTE: this method expects @topology's mutex to be locked on entry.
624662
*
@@ -633,18 +671,9 @@ mongoc_topology_rescan_srv (mongoc_topology_t *topology)
633671
int64_t scan_time_ms;
634672
bool ret;
635673

636-
if ((topology->description.type != MONGOC_TOPOLOGY_SHARDED) &&
637-
(topology->description.type != MONGOC_TOPOLOGY_UNKNOWN)) {
638-
/* Only perform rescan for sharded topology. */
639-
return;
640-
}
674+
BSON_ASSERT (mongoc_topology_should_rescan_srv (topology));
641675

642676
service = mongoc_uri_get_service (topology->uri);
643-
if (!service) {
644-
/* Only rescan if we have a mongodb+srv:// URI. */
645-
return;
646-
}
647-
648677
scan_time_ms = topology->srv_polling_last_scan_ms +
649678
topology->srv_polling_rescan_interval_ms;
650679
if (bson_get_monotonic_time () / 1000 < scan_time_ms) {
@@ -723,8 +752,10 @@ mongoc_topology_rescan_srv (mongoc_topology_t *topology)
723752
static void
724753
mongoc_topology_scan_once (mongoc_topology_t *topology, bool obey_cooldown)
725754
{
726-
/* Prior to scanning hosts, update the list of SRV hosts, if applicable. */
727-
mongoc_topology_rescan_srv (topology);
755+
if (mongoc_topology_should_rescan_srv (topology)) {
756+
/* Prior to scanning hosts, update the list of SRV hosts, if applicable. */
757+
mongoc_topology_rescan_srv (topology);
758+
}
728759

729760
/* since the last scan, members may be added or removed from the topology
730761
* description based on ismaster responses in connection handshakes, see

0 commit comments

Comments
 (0)