Skip to content

Commit 5916dda

Browse files
committed
CDRIVER-3532 unify behavior around configuration for replica set discovery
1 parent 11a8746 commit 5916dda

File tree

7 files changed

+324
-4
lines changed

7 files changed

+324
-4
lines changed
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
:man_page: mongoc_uri_has_option
2+
3+
mongoc_uri_has_option()
4+
=======================
5+
6+
Synopsis
7+
--------
8+
9+
.. code-block:: c
10+
11+
bool
12+
mongoc_uri_has_option (const mongoc_uri_t *uri, const char *option);
13+
14+
Parameters
15+
----------
16+
17+
* ``uri``: A :symbol:`mongoc_uri_t`.
18+
* ``option``: The name of an option, case insensitive.
19+
20+
Description
21+
-----------
22+
23+
Returns true if the option was present in the initial MongoDB URI.
24+

src/libmongoc/doc/mongoc_uri_t.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,7 @@ MONGOC_URI_HEARTBEATFREQUENCYMS heartbeatfrequencyms The
174174
MONGOC_URI_SERVERSELECTIONTIMEOUTMS serverselectiontimeoutms A timeout in milliseconds to block for server selection before throwing an exception. The default is 30,0000ms (30 seconds).
175175
MONGOC_URI_SERVERSELECTIONTRYONCE serverselectiontryonce If "true", the driver scans the topology exactly once after server selection fails, then either selects a server or returns an error. If it is false, then the driver repeatedly searches for a suitable server for up to ``serverSelectionTimeoutMS`` milliseconds (pausing a half second between attempts). The default for ``serverSelectionTryOnce`` is "false" for pooled clients, otherwise "true". Pooled clients ignore serverSelectionTryOnce; they signal the thread to rescan the topology every half-second until serverSelectionTimeoutMS expires.
176176
MONGOC_URI_SOCKETCHECKINTERVALMS socketcheckintervalms Only applies to single threaded clients. If a socket has not been used within this time, its connection is checked with a quick "isMaster" call before it is used again. Defaults to 5,000ms (5 seconds).
177+
MONGOC_URI_DIRECTCONNECTION directconnection If "true", the driver connects to a single server directly and will not monitor additional servers. If "false", the driver connects based on the presence and value of the ``replicaSet`` option.
177178
========================================== ================================= =========================================================================================================================================================================================================================
178179

179180
Setting any of the \*TimeoutMS options above to ``0`` will be interpreted as "use the default value".
@@ -303,6 +304,7 @@ MONGOC_URI_SLAVEOK slaveok Whe
303304
mongoc_uri_get_tls
304305
mongoc_uri_get_username
305306
mongoc_uri_get_write_concern
307+
mongoc_uri_has_option
306308
mongoc_uri_new
307309
mongoc_uri_new_for_host_port
308310
mongoc_uri_new_with_error

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

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,8 @@ mongoc_topology_new (const mongoc_uri_t *uri, bool single_threaded)
210210
uint32_t id;
211211
const mongoc_host_list_t *hl;
212212
mongoc_rr_data_t rr_data;
213+
bool has_directconnection;
214+
bool directconnection;
213215

214216
BSON_ASSERT (uri);
215217

@@ -328,12 +330,35 @@ mongoc_topology_new (const mongoc_uri_t *uri, bool single_threaded)
328330

329331
/*
330332
* Set topology type from URI:
331-
* - if we've got a replicaSet name, initialize to RS_NO_PRIMARY
332-
* - otherwise, if the seed list has a single host, initialize to SINGLE
333+
* + if directConnection=true
334+
* - whether or not we have a replicaSet name, initialize to SINGLE
335+
* (directConnect with SRV or multiple hosts triggers a URI parse error)
336+
* + if directConnection=false
337+
* - if we've got a replicaSet name, initialize to RS_NO_PRIMARY
338+
* - otherwise, initialize to UNKNOWN
339+
* + if directConnection was not specified in the URI (old behavior)
340+
* - if we've got a replicaSet name, initialize to RS_NO_PRIMARY
341+
* - otherwise, if the seed list has a single host, initialize to SINGLE
333342
* - everything else gets initialized to UNKNOWN
334343
*/
344+
has_directconnection = mongoc_uri_has_option (
345+
uri, MONGOC_URI_DIRECTCONNECTION);
346+
directconnection = has_directconnection &&
347+
mongoc_uri_get_option_as_bool (uri, MONGOC_URI_DIRECTCONNECTION, false);
335348
hl = mongoc_uri_get_hosts (topology->uri);
336-
if (mongoc_uri_get_replica_set (topology->uri)) {
349+
if (service && !has_directconnection) {
350+
init_type = MONGOC_TOPOLOGY_UNKNOWN;
351+
} else if (has_directconnection) {
352+
if (directconnection) {
353+
init_type = MONGOC_TOPOLOGY_SINGLE;
354+
} else {
355+
if (mongoc_uri_get_replica_set (topology->uri)) {
356+
init_type = MONGOC_TOPOLOGY_RS_NO_PRIMARY;
357+
} else {
358+
init_type = MONGOC_TOPOLOGY_UNKNOWN;
359+
}
360+
}
361+
} else if (mongoc_uri_get_replica_set (topology->uri)) {
337362
init_type = MONGOC_TOPOLOGY_RS_NO_PRIMARY;
338363
} else {
339364
if (hl && hl->next) {
@@ -1656,4 +1681,4 @@ _mongoc_topology_bypass_cooldown (mongoc_topology_t *topology)
16561681
{
16571682
BSON_ASSERT (topology->single_threaded);
16581683
topology->scanner->bypass_cooldown = true;
1659-
}
1684+
}

src/libmongoc/src/mongoc/mongoc-uri.c

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -702,6 +702,14 @@ mongoc_uri_bson_append_or_replace_key (bson_t *options,
702702
}
703703

704704

705+
bool
706+
mongoc_uri_has_option (const mongoc_uri_t *uri, const char *key)
707+
{
708+
bson_iter_t iter;
709+
710+
return bson_iter_init_find_case (&iter, &uri->options, key);
711+
}
712+
705713
bool
706714
mongoc_uri_option_is_int32 (const char *key)
707715
{
@@ -731,6 +739,7 @@ bool
731739
mongoc_uri_option_is_bool (const char *key)
732740
{
733741
return !strcasecmp (key, MONGOC_URI_CANONICALIZEHOSTNAME) ||
742+
!strcasecmp (key, MONGOC_URI_DIRECTCONNECTION) ||
734743
!strcasecmp (key, MONGOC_URI_JOURNAL) ||
735744
!strcasecmp (key, MONGOC_URI_RETRYREADS) ||
736745
!strcasecmp (key, MONGOC_URI_RETRYWRITES) ||
@@ -1390,6 +1399,41 @@ mongoc_uri_finalize_auth (mongoc_uri_t *uri,
13901399
return true;
13911400
}
13921401

1402+
static bool
1403+
mongoc_uri_finalize_directconnection (mongoc_uri_t *uri, bson_error_t *error)
1404+
{
1405+
bool directconnection = false;
1406+
1407+
directconnection =
1408+
mongoc_uri_get_option_as_bool (uri, MONGOC_URI_DIRECTCONNECTION, false);
1409+
if (!directconnection) {
1410+
return true;
1411+
}
1412+
1413+
/* URI options spec: "The driver MUST report an error if the
1414+
* directConnection=true URI option is specified with an SRV URI, because
1415+
* the URI may resolve to multiple hosts. The driver MUST allow specifying
1416+
* directConnection=false URI option with an SRV URI." */
1417+
if (uri->is_srv) {
1418+
MONGOC_URI_ERROR (
1419+
error, "%s", "SRV URI not allowed with directConnection option");
1420+
return false;
1421+
}
1422+
1423+
/* URI options spec: "The driver MUST report an error if the
1424+
* directConnection=true URI option is specified with multiple seeds." */
1425+
if (uri->hosts && uri->hosts->next) {
1426+
MONGOC_URI_ERROR (
1427+
error,
1428+
"%s",
1429+
"Multiple seeds not allowed with directConnection option");
1430+
return false;
1431+
}
1432+
1433+
return true;
1434+
1435+
}
1436+
13931437
static bool
13941438
mongoc_uri_parse_before_slash (mongoc_uri_t *uri,
13951439
const char *before_slash,
@@ -1502,6 +1546,10 @@ mongoc_uri_parse (mongoc_uri_t *uri, const char *str, bson_error_t *error)
15021546
goto error;
15031547
}
15041548

1549+
if (!mongoc_uri_finalize_directconnection (uri, error)) {
1550+
goto error;
1551+
}
1552+
15051553
bson_free (before_slash);
15061554
return true;
15071555

src/libmongoc/src/mongoc/mongoc-uri.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
#define MONGOC_URI_CANONICALIZEHOSTNAME "canonicalizehostname"
4141
#define MONGOC_URI_CONNECTTIMEOUTMS "connecttimeoutms"
4242
#define MONGOC_URI_COMPRESSORS "compressors"
43+
#define MONGOC_URI_DIRECTCONNECTION "directconnection"
4344
#define MONGOC_URI_GSSAPISERVICENAME "gssapiservicename"
4445
#define MONGOC_URI_HEARTBEATFREQUENCYMS "heartbeatfrequencyms"
4546
#define MONGOC_URI_JOURNAL "journal"
@@ -120,6 +121,8 @@ mongoc_uri_get_password (const mongoc_uri_t *uri);
120121
MONGOC_EXPORT (bool)
121122
mongoc_uri_set_password (mongoc_uri_t *uri, const char *password);
122123
MONGOC_EXPORT (bool)
124+
mongoc_uri_has_option (const mongoc_uri_t *uri, const char *key);
125+
MONGOC_EXPORT (bool)
123126
mongoc_uri_option_is_int32 (const char *key);
124127
MONGOC_EXPORT (bool)
125128
mongoc_uri_option_is_int64 (const char *key);

0 commit comments

Comments
 (0)