Skip to content

Commit 7e60c3c

Browse files
authored
Patch in necessary libmongoc fixes for 1.0 (#489)
1 parent daa6a2c commit 7e60c3c

File tree

7 files changed

+259
-4
lines changed

7 files changed

+259
-4
lines changed

Sources/CLibMongoC/include/CLibMongoC_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"
@@ -117,6 +118,8 @@ mongoc_uri_get_password (const mongoc_uri_t *uri);
117118
MONGOC_EXPORT (bool)
118119
mongoc_uri_set_password (mongoc_uri_t *uri, const char *password);
119120
MONGOC_EXPORT (bool)
121+
mongoc_uri_has_option (const mongoc_uri_t *uri, const char *key);
122+
MONGOC_EXPORT (bool)
120123
mongoc_uri_option_is_int32 (const char *key);
121124
MONGOC_EXPORT (bool)
122125
mongoc_uri_option_is_int64 (const char *key);

Sources/CLibMongoC/mongoc/mongoc-client.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2670,7 +2670,11 @@ _mongoc_client_set_apm_callbacks_private (mongoc_client_t *client,
26702670
}
26712671

26722672
client->apm_context = context;
2673-
mongoc_topology_set_apm_callbacks (client->topology, callbacks, context);
2673+
2674+
/* A client pool sets APM callbacks for the entire pool. */
2675+
if (client->topology->single_threaded) {
2676+
mongoc_topology_set_apm_callbacks (client->topology, callbacks, context);
2677+
}
26742678

26752679
return true;
26762680
}

Sources/CLibMongoC/mongoc/mongoc-topology.c

Lines changed: 28 additions & 3 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) {

Sources/CLibMongoC/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) ||
@@ -1335,6 +1344,41 @@ mongoc_uri_finalize_auth (mongoc_uri_t *uri,
13351344
return true;
13361345
}
13371346

1347+
static bool
1348+
mongoc_uri_finalize_directconnection (mongoc_uri_t *uri, bson_error_t *error)
1349+
{
1350+
bool directconnection = false;
1351+
1352+
directconnection =
1353+
mongoc_uri_get_option_as_bool (uri, MONGOC_URI_DIRECTCONNECTION, false);
1354+
if (!directconnection) {
1355+
return true;
1356+
}
1357+
1358+
/* URI options spec: "The driver MUST report an error if the
1359+
* directConnection=true URI option is specified with an SRV URI, because
1360+
* the URI may resolve to multiple hosts. The driver MUST allow specifying
1361+
* directConnection=false URI option with an SRV URI." */
1362+
if (uri->is_srv) {
1363+
MONGOC_URI_ERROR (
1364+
error, "%s", "SRV URI not allowed with directConnection option");
1365+
return false;
1366+
}
1367+
1368+
/* URI options spec: "The driver MUST report an error if the
1369+
* directConnection=true URI option is specified with multiple seeds." */
1370+
if (uri->hosts && uri->hosts->next) {
1371+
MONGOC_URI_ERROR (
1372+
error,
1373+
"%s",
1374+
"Multiple seeds not allowed with directConnection option");
1375+
return false;
1376+
}
1377+
1378+
return true;
1379+
1380+
}
1381+
13381382
static bool
13391383
mongoc_uri_parse_before_slash (mongoc_uri_t *uri,
13401384
const char *before_slash,
@@ -1447,6 +1491,10 @@ mongoc_uri_parse (mongoc_uri_t *uri, const char *str, bson_error_t *error)
14471491
goto error;
14481492
}
14491493

1494+
if (!mongoc_uri_finalize_directconnection (uri, error)) {
1495+
goto error;
1496+
}
1497+
14501498
bson_free (before_slash);
14511499
return true;
14521500

Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
diff --git a/Sources/CLibMongoC/mongoc/mongoc-topology.c b/Sources/CLibMongoC/mongoc/mongoc-topology.c
2+
index 987f98e4e..7b9136bfc 100644
3+
--- a/Sources/CLibMongoC/mongoc/mongoc-topology.c
4+
+++ a/Sources/CLibMongoC/mongoc/mongoc-topology.c
5+
@@ -210,6 +210,8 @@ mongoc_topology_new (const mongoc_uri_t *uri, bool single_threaded)
6+
uint32_t id;
7+
const mongoc_host_list_t *hl;
8+
mongoc_rr_data_t rr_data;
9+
+ bool has_directconnection;
10+
+ bool directconnection;
11+
12+
BSON_ASSERT (uri);
13+
14+
@@ -328,12 +330,35 @@ mongoc_topology_new (const mongoc_uri_t *uri, bool single_threaded)
15+
16+
/*
17+
* Set topology type from URI:
18+
- * - if we've got a replicaSet name, initialize to RS_NO_PRIMARY
19+
- * - otherwise, if the seed list has a single host, initialize to SINGLE
20+
+ * + if directConnection=true
21+
+ * - whether or not we have a replicaSet name, initialize to SINGLE
22+
+ * (directConnect with SRV or multiple hosts triggers a URI parse error)
23+
+ * + if directConnection=false
24+
+ * - if we've got a replicaSet name, initialize to RS_NO_PRIMARY
25+
+ * - otherwise, initialize to UNKNOWN
26+
+ * + if directConnection was not specified in the URI (old behavior)
27+
+ * - if we've got a replicaSet name, initialize to RS_NO_PRIMARY
28+
+ * - otherwise, if the seed list has a single host, initialize to SINGLE
29+
* - everything else gets initialized to UNKNOWN
30+
*/
31+
+ has_directconnection = mongoc_uri_has_option (
32+
+ uri, MONGOC_URI_DIRECTCONNECTION);
33+
+ directconnection = has_directconnection &&
34+
+ mongoc_uri_get_option_as_bool (uri, MONGOC_URI_DIRECTCONNECTION, false);
35+
hl = mongoc_uri_get_hosts (topology->uri);
36+
- if (mongoc_uri_get_replica_set (topology->uri)) {
37+
+ if (service && !has_directconnection) {
38+
+ init_type = MONGOC_TOPOLOGY_UNKNOWN;
39+
+ } else if (has_directconnection) {
40+
+ if (directconnection) {
41+
+ init_type = MONGOC_TOPOLOGY_SINGLE;
42+
+ } else {
43+
+ if (mongoc_uri_get_replica_set (topology->uri)) {
44+
+ init_type = MONGOC_TOPOLOGY_RS_NO_PRIMARY;
45+
+ } else {
46+
+ init_type = MONGOC_TOPOLOGY_UNKNOWN;
47+
+ }
48+
+ }
49+
+ } else if (mongoc_uri_get_replica_set (topology->uri)) {
50+
init_type = MONGOC_TOPOLOGY_RS_NO_PRIMARY;
51+
} else {
52+
if (hl && hl->next) {
53+
diff --git a/Sources/CLibMongoC/mongoc/mongoc-uri.c b/Sources/CLibMongoC/mongoc/mongoc-uri.c
54+
index 8e6fa149e..31ac05272 100644
55+
--- a/Sources/CLibMongoC/mongoc/mongoc-uri.c
56+
+++ b/Sources/CLibMongoC/mongoc/mongoc-uri.c
57+
@@ -702,6 +702,14 @@ mongoc_uri_bson_append_or_replace_key (bson_t *options,
58+
}
59+
60+
61+
+bool
62+
+mongoc_uri_has_option (const mongoc_uri_t *uri, const char *key)
63+
+{
64+
+ bson_iter_t iter;
65+
+
66+
+ return bson_iter_init_find_case (&iter, &uri->options, key);
67+
+}
68+
+
69+
bool
70+
mongoc_uri_option_is_int32 (const char *key)
71+
{
72+
@@ -731,6 +739,7 @@ bool
73+
mongoc_uri_option_is_bool (const char *key)
74+
{
75+
return !strcasecmp (key, MONGOC_URI_CANONICALIZEHOSTNAME) ||
76+
+ !strcasecmp (key, MONGOC_URI_DIRECTCONNECTION) ||
77+
!strcasecmp (key, MONGOC_URI_JOURNAL) ||
78+
!strcasecmp (key, MONGOC_URI_RETRYREADS) ||
79+
!strcasecmp (key, MONGOC_URI_RETRYWRITES) ||
80+
@@ -1390,6 +1399,41 @@ mongoc_uri_finalize_auth (mongoc_uri_t *uri,
81+
return true;
82+
}
83+
84+
+static bool
85+
+mongoc_uri_finalize_directconnection (mongoc_uri_t *uri, bson_error_t *error)
86+
+{
87+
+ bool directconnection = false;
88+
+
89+
+ directconnection =
90+
+ mongoc_uri_get_option_as_bool (uri, MONGOC_URI_DIRECTCONNECTION, false);
91+
+ if (!directconnection) {
92+
+ return true;
93+
+ }
94+
+
95+
+ /* URI options spec: "The driver MUST report an error if the
96+
+ * directConnection=true URI option is specified with an SRV URI, because
97+
+ * the URI may resolve to multiple hosts. The driver MUST allow specifying
98+
+ * directConnection=false URI option with an SRV URI." */
99+
+ if (uri->is_srv) {
100+
+ MONGOC_URI_ERROR (
101+
+ error, "%s", "SRV URI not allowed with directConnection option");
102+
+ return false;
103+
+ }
104+
+
105+
+ /* URI options spec: "The driver MUST report an error if the
106+
+ * directConnection=true URI option is specified with multiple seeds." */
107+
+ if (uri->hosts && uri->hosts->next) {
108+
+ MONGOC_URI_ERROR (
109+
+ error,
110+
+ "%s",
111+
+ "Multiple seeds not allowed with directConnection option");
112+
+ return false;
113+
+ }
114+
+
115+
+ return true;
116+
+
117+
+}
118+
+
119+
static bool
120+
mongoc_uri_parse_before_slash (mongoc_uri_t *uri,
121+
const char *before_slash,
122+
@@ -1502,6 +1546,10 @@ mongoc_uri_parse (mongoc_uri_t *uri, const char *str, bson_error_t *error)
123+
goto error;
124+
}
125+
126+
+ if (!mongoc_uri_finalize_directconnection (uri, error)) {
127+
+ goto error;
128+
+ }
129+
+
130+
bson_free (before_slash);
131+
return true;
132+
133+
diff --git a/Sources/CLibMongoC/include/CLibMongoC_mongoc-uri.h b/Sources/CLibMongoC/include/CLibMongoC_mongoc-uri.h
134+
index a190b1f71..e08b7d43f 100644
135+
--- a/Sources/CLibMongoC/include/CLibMongoC_mongoc-uri.h
136+
+++ b/Sources/CLibMongoC/include/CLibMongoC_mongoc-uri.h
137+
@@ -40,6 +40,7 @@
138+
#define MONGOC_URI_CANONICALIZEHOSTNAME "canonicalizehostname"
139+
#define MONGOC_URI_CONNECTTIMEOUTMS "connecttimeoutms"
140+
#define MONGOC_URI_COMPRESSORS "compressors"
141+
+#define MONGOC_URI_DIRECTCONNECTION "directconnection"
142+
#define MONGOC_URI_GSSAPISERVICENAME "gssapiservicename"
143+
#define MONGOC_URI_HEARTBEATFREQUENCYMS "heartbeatfrequencyms"
144+
#define MONGOC_URI_JOURNAL "journal"
145+
@@ -120,6 +121,8 @@ mongoc_uri_get_password (const mongoc_uri_t *uri);
146+
MONGOC_EXPORT (bool)
147+
mongoc_uri_set_password (mongoc_uri_t *uri, const char *password);
148+
MONGOC_EXPORT (bool)
149+
+mongoc_uri_has_option (const mongoc_uri_t *uri, const char *key);
150+
+MONGOC_EXPORT (bool)
151+
mongoc_uri_option_is_int32 (const char *key);
152+
MONGOC_EXPORT (bool)
153+
mongoc_uri_option_is_int64 (const char *key);
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
diff --git a/Sources/CLibMongoC/mongoc/mongoc-client.c b/Sources/CLibMongoC/mongoc/mongoc-client.c
2+
index ea17e356c..77abca8e0 100644
3+
--- a/Sources/CLibMongoC/mongoc/mongoc-client.c
4+
+++ b/Sources/CLibMongoC/mongoc/mongoc-client.c
5+
@@ -2689,7 +2689,11 @@ _mongoc_client_set_apm_callbacks_private (mongoc_client_t *client,
6+
}
7+
8+
client->apm_context = context;
9+
- mongoc_topology_set_apm_callbacks (client->topology, callbacks, context);
10+
+
11+
+ /* A client pool sets APM callbacks for the entire pool. */
12+
+ if (client->topology->single_threaded) {
13+
+ mongoc_topology_set_apm_callbacks (client->topology, callbacks, context);
14+
+ }
15+
16+
return true;
17+
}

etc/vendor-libmongoc.sh

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,11 @@ echo "RENAMING header files"
131131
echo "PATCHING libmongoc"
132132
git apply "${ETC_DIR}/inttypes-non-modular-header-workaround.diff"
133133

134+
# These patches are temporary workarounds to give us early access to the directConnection URI option and a bug fix.
135+
# This should be removed from the script when we update our vendored libmongoc to 1.17 via SWIFT-766.
136+
git apply "${ETC_DIR}/CDRIVER-3532-directConnection.diff"
137+
git apply "${ETC_DIR}/CDRIVER-3623-fix-setting-apm-in-pooled-client.diff"
138+
134139
# Clang modules are build by a conventional structure with an `include` folder for public
135140
# includes, and an umbrella header used as the primary entry point. As part of the vendoring
136141
# process, we copy in our own handwritten umbrella file. Currently, there is no generated

0 commit comments

Comments
 (0)