Skip to content

Commit 9e280c8

Browse files
committed
CDRIVER-699 introduce serverSelectionTryOnce option
1 parent 6febfb6 commit 9e280c8

File tree

5 files changed

+63
-0
lines changed

5 files changed

+63
-0
lines changed

doc/mongoc_uri_t.page

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,8 @@
6969
<table>
7070
<tr><td><p>heartbeatFrequencyMS</p></td><td><p>The interval between server monitoring checks. Defaults to 10 seconds in multi-threaded mode, 60 seconds in single threaded.</p></td></tr>
7171
<tr><td><p>serverSelectionTimeoutMS</p></td><td><p>A timeout in milliseconds to block for server selection before throwing an exception. The default is 30,000 (milliseconds).</p></td></tr>
72+
<tr><td><p>serverSelectionTryOnce</p></td><td><p>If "true" (the default), the driver scans the topology exactly once after server selection fails, then either selects a server or raises an error. If it is false, then the driver repeatedly searches for an appropriate server for up to serverSelectionTimeoutMS milliseconds (pausing a half second between attempts).</p>
73+
<p>Clients in a <code xref="mongoc_client_pool_t">mongoc_client_pool_t</code> share a topology scanner that runs on a background thread. Pooled clients ignore serverSelectionTryOnce; they signal the thread to rescan the topology every half-second until serverSelectionTimeoutMS expires.</p></td></tr>
7274
<tr><td><p>socketCheckIntervalMS</p></td><td><p>Only applicable to single threaded clients. If socket has not been used within this timeframe a isMaster call is attempted. Defaults to 5 seconds.</p></td></tr>
7375
</table>
7476
<note style="important">

src/mongoc/mongoc-topology-private.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ typedef struct _mongoc_topology_t
4242
mongoc_topology_description_t description;
4343
mongoc_uri_t *uri;
4444
mongoc_topology_scanner_t *scanner;
45+
bool server_selection_try_once;
4546

4647
int64_t last_scan;
4748
int64_t timeout_msec;

src/mongoc/mongoc-topology.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,23 @@ mongoc_topology_new (const mongoc_uri_t *uri,
170170
_mongoc_topology_scanner_cb,
171171
topology);
172172
topology->single_threaded = single_threaded;
173+
if (single_threaded) {
174+
/* Server Selection Spec:
175+
*
176+
* "Single-threaded drivers MUST provide a "serverSelectionTryOnce"
177+
* mode, in which the driver scans the topology exactly once after
178+
* server selection fails, then either selects a server or raises an
179+
* error.
180+
*
181+
* "The serverSelectionTryOnce option MUST be true by default."
182+
*/
183+
topology->server_selection_try_once = mongoc_uri_get_option_as_bool (
184+
uri,
185+
"serverselectiontryonce",
186+
true);
187+
} else {
188+
topology->server_selection_try_once = false;
189+
}
173190

174191
topology->timeout_msec = mongoc_uri_get_option_as_int32(
175192
topology->uri, "serverselectiontimeoutms",

src/mongoc/mongoc-uri.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -557,6 +557,7 @@ mongoc_uri_option_is_bool (const char *key)
557557
return !strcasecmp(key, "canonicalizeHostname") ||
558558
!strcasecmp(key, "journal") ||
559559
!strcasecmp(key, "safe") ||
560+
!strcasecmp(key, "serverSelectionTryOnce") ||
560561
!strcasecmp(key, "slaveok") ||
561562
!strcasecmp(key, "ssl");
562563
}

tests/test-mongoc-topology.c

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,44 @@ test_topology_client_pool_creation (void)
9292
mongoc_client_pool_destroy (pool);
9393
}
9494

95+
static void
96+
test_server_selection_try_once_option (void)
97+
{
98+
const char *uri_strings[3] = {
99+
"mongodb://a",
100+
"mongodb://a/?serverSelectionTryOnce=true",
101+
"mongodb://a/?serverSelectionTryOnce=false" };
102+
103+
int i;
104+
mongoc_client_t *client;
105+
mongoc_uri_t *uri;
106+
mongoc_client_pool_t *pool;
107+
108+
/* try_once is on by default for non-pooled, can be turned off */
109+
client = mongoc_client_new (uri_strings[0]);
110+
assert (client->topology->server_selection_try_once);
111+
mongoc_client_destroy (client);
112+
113+
client = mongoc_client_new (uri_strings[1]);
114+
assert (client->topology->server_selection_try_once);
115+
mongoc_client_destroy (client);
116+
117+
client = mongoc_client_new (uri_strings[2]);
118+
assert (! client->topology->server_selection_try_once);
119+
mongoc_client_destroy (client);
120+
121+
/* off for pooled clients, can't be enabled */
122+
for (i = 0; i < sizeof (uri_strings) / sizeof (char *); i++) {
123+
uri = mongoc_uri_new ("mongodb://a");
124+
pool = mongoc_client_pool_new (uri);
125+
client = mongoc_client_pool_pop (pool);
126+
assert (!client->topology->server_selection_try_once);
127+
mongoc_client_pool_push (pool, client);
128+
mongoc_client_pool_destroy (pool);
129+
mongoc_uri_destroy (uri);
130+
}
131+
}
132+
95133
static void
96134
test_topology_invalidate_server (void)
97135
{
@@ -402,6 +440,10 @@ test_topology_install (TestSuite *suite)
402440
{
403441
TestSuite_Add (suite, "/Topology/client_creation", test_topology_client_creation);
404442
TestSuite_Add (suite, "/Topology/client_pool_creation", test_topology_client_pool_creation);
443+
TestSuite_Add (suite,
444+
"/Topology/server_selection_try_once_option",
445+
test_server_selection_try_once_option);
446+
405447
TestSuite_Add (suite, "/Topology/invalidate_server", test_topology_invalidate_server);
406448
TestSuite_Add (suite, "/Topology/invalid_cluster_node", test_invalid_cluster_node);
407449
TestSuite_Add (suite, "/Topology/max_wire_version_race_condition", test_max_wire_version_race_condition);

0 commit comments

Comments
 (0)