Skip to content

Commit e165275

Browse files
committed
WIP
1 parent d1c6507 commit e165275

8 files changed

+152
-0
lines changed
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
:man_page: mongoc_server_description_service_id
2+
3+
mongoc_server_description_service_id()
4+
======================================
5+
6+
// LBTODO

src/libmongoc/src/mongoc/mongoc-cluster.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2281,6 +2281,8 @@ _mongoc_cluster_stream_for_server (mongoc_cluster_t *cluster,
22812281
_mongoc_bson_init_with_transient_txn_error (cs, reply);
22822282
}
22832283

2284+
// LBTODO: if this is a load balanced topology and the server stream does not have a service id, disconnect and return an error.
2285+
22842286
RETURN (server_stream);
22852287
}
22862288

src/libmongoc/src/mongoc/mongoc-server-description.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -723,6 +723,7 @@ mongoc_server_description_handle_hello (mongoc_server_description_t *sd,
723723
sd, &incoming_topology_version);
724724
bson_destroy (&incoming_topology_version);
725725
}
726+
// LBTODO: process serviceID
726727
}
727728

728729
if (is_shard) {
@@ -1238,3 +1239,10 @@ mongoc_server_description_set_topology_version (mongoc_server_description_t *sd,
12381239
bson_destroy (&sd->topology_version);
12391240
bson_copy_to (tv, &sd->topology_version);
12401241
}
1242+
1243+
bool
1244+
mongoc_server_description_service_id (const mongoc_server_description_t *description, bson_oid_t *oid) {
1245+
// LBTODO
1246+
memset (oid, 0, sizeof (bson_oid_t));
1247+
return false;
1248+
}

src/libmongoc/src/mongoc/mongoc-server-description.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,10 @@ MONGOC_EXPORT (int32_t)
6666
mongoc_server_description_compressor_id (
6767
const mongoc_server_description_t *description);
6868

69+
// LBTODO
70+
MONGOC_EXPORT (bool)
71+
mongoc_server_description_service_id (const mongoc_server_description_t *description, bson_oid_t *oid);
72+
6973
BSON_END_DECLS
7074

7175
#endif

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ typedef struct mongoc_topology_scanner_node {
8383
/* handshake_sd is a server description constructed from the response of the
8484
* initial handshake. It is bound to the lifetime of stream. */
8585
mongoc_server_description_t *handshake_sd;
86+
bool loadbalanced;
8687
} mongoc_topology_scanner_node_t;
8788

8889
typedef struct mongoc_topology_scanner {
@@ -241,6 +242,9 @@ void
241242
_mongoc_topology_scanner_set_server_api (mongoc_topology_scanner_t *ts,
242243
const mongoc_server_api_t *api);
243244

245+
void
246+
_mongoc_topology_scanner_set_loadbalanced (mongoc_topology_scanner_t *ts, bool val);
247+
244248
/* for testing. */
245249
mongoc_stream_t *
246250
_mongoc_topology_scanner_tcp_initiate (mongoc_async_cmd_t *acmd);

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

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,8 @@ _build_handshake_cmd (mongoc_topology_scanner_t *ts)
260260
bson_destroy (doc);
261261
bson_copy_to (ts->api ? &ts->hello_cmd : &ts->legacy_hello_cmd, doc);
262262

263+
// LBTODO: if ts->loadbalanced, append loadBalanced: true
264+
263265
BSON_APPEND_DOCUMENT_BEGIN (doc, HANDSHAKE_FIELD, &subdoc);
264266
res = _mongoc_handshake_build_doc_with_application (&subdoc, ts->appname);
265267
bson_append_document_end (doc, &subdoc);
@@ -1398,3 +1400,10 @@ _mongoc_topology_scanner_set_server_api (mongoc_topology_scanner_t *ts,
13981400
ts->api = mongoc_server_api_copy (api);
13991401
_reset_hello (ts);
14001402
}
1403+
1404+
/* This must be called before the handshake command is constructed. Caller does not need to lock the topology->mutex. */
1405+
void
1406+
_mongoc_topology_scanner_set_loadbalanced (mongoc_topology_scanner_t *ts, bool val) {
1407+
BSON_ASSERT (bson_empty (&ts->handshake_cmd));
1408+
ts->loadbalanced = true;
1409+
}

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -434,6 +434,7 @@ mongoc_topology_new (const mongoc_uri_t *uri, bool single_threaded)
434434
if (topology->single_threaded) {
435435
_mongoc_topology_bypass_cooldown (topology);
436436
}
437+
_mongoc_topology_scanner_set_loadbalanced (topology->scanner, true);
437438
} else if (service && !has_directconnection) {
438439
init_type = MONGOC_TOPOLOGY_UNKNOWN;
439440
} else if (has_directconnection) {

src/libmongoc/tests/test-mongoc-loadbalanced.c

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@
2020
#include "test-libmongoc.h"
2121
#include "TestSuite.h"
2222

23+
#include "mock_server/future-functions.h"
24+
#include "mock_server/mock-server.h"
25+
#include "mock_server/request.h"
26+
2327
typedef struct {
2428
int server_changed_events;
2529
int server_opening_events;
@@ -433,6 +437,112 @@ test_loadbalanced_cooldown_is_bypassed_single (void *unused)
433437
free_and_assert_stats (stats);
434438
}
435439

440+
/* Tests:
441+
* - loadBalanced: true is added to the handshake
442+
* - serviceID is set in the server description.
443+
*/
444+
#define LB_HELLO \
445+
"{'ismaster': true, 'maxWireVersion': 13, 'msg': 'isdbgrid', 'serviceID', " \
446+
"{'$oid': 'AAAAAAAAAAAAAAAAAAAAAAAA'}}"
447+
static void
448+
test_loadbalanced_handshake_sends_loadbalanced (void)
449+
{
450+
mock_server_t *server;
451+
mongoc_client_t *client;
452+
mongoc_uri_t *uri;
453+
request_t *request;
454+
future_t *future;
455+
bson_error_t error;
456+
mongoc_server_description_t *monitor_sd;
457+
mongoc_server_description_t *handshake_sd;
458+
bson_oid_t expected;
459+
bson_oid_t actual;
460+
461+
server = mock_server_new ();
462+
mock_server_run (server);
463+
uri = mongoc_uri_copy (mock_server_get_uri (server));
464+
mongoc_uri_set_option_as_bool (uri, MONGOC_URI_LOADBALANCED, true);
465+
client = mongoc_client_new_from_uri (uri);
466+
467+
future = future_client_command_simple (client,
468+
"admin",
469+
tmp_bson ("{'ping': 1}"),
470+
NULL /* read prefs */,
471+
NULL /* reply */,
472+
&error);
473+
request =
474+
mock_server_receives_legacy_hello (server, "{'loadBalanced': true}");
475+
mock_server_replies_simple (request, LB_HELLO);
476+
request_destroy (request);
477+
478+
request = mock_server_receives_msg (server, 0, tmp_bson ("{'ping': 1}"));
479+
mock_server_replies_ok_and_destroys (request);
480+
481+
ASSERT_OR_PRINT (future_get_bool (future), error);
482+
future_destroy (future);
483+
484+
monitor_sd = mongoc_client_select_server (
485+
client, true /* for writes */, NULL /* read prefs */, &error);
486+
ASSERT_OR_PRINT (monitor_sd, error);
487+
handshake_sd = mongoc_client_get_handshake_description (
488+
client, 1, NULL /* opts */, &error);
489+
ASSERT_OR_PRINT (handshake_sd, error);
490+
491+
bson_oid_init_from_string (&expected, "AAAAAAAAAAAAAAAAAAAAAAAA");
492+
BSON_ASSERT (mongoc_server_description_service_id (handshake_sd, &actual));
493+
ASSERT_CMPOID (&actual, &expected);
494+
495+
mongoc_server_description_destroy (handshake_sd);
496+
mongoc_server_description_destroy (monitor_sd);
497+
mongoc_uri_destroy (uri);
498+
mongoc_client_destroy (client);
499+
mock_server_destroy (server);
500+
}
501+
502+
/* Tests that a connection is rejected if the handshake reply does not include a
503+
* serviceID field. */
504+
#define NON_LB_HELLO \
505+
"{'ismaster': true, 'maxWireVersion': 13, 'msg': 'isdbgrid'}"
506+
static void
507+
test_loadbalanced_handshake_rejects_non_loadbalanced (void)
508+
{
509+
mock_server_t *server;
510+
mongoc_client_t *client;
511+
mongoc_uri_t *uri;
512+
request_t *request;
513+
future_t *future;
514+
bson_error_t error;
515+
516+
server = mock_server_new ();
517+
mock_server_run (server);
518+
uri = mongoc_uri_copy (mock_server_get_uri (server));
519+
mongoc_uri_set_option_as_bool (uri, MONGOC_URI_LOADBALANCED, true);
520+
client = mongoc_client_new_from_uri (uri);
521+
522+
future = future_client_command_simple (client,
523+
"admin",
524+
tmp_bson ("{'ping': 1}"),
525+
NULL /* read prefs */,
526+
NULL /* reply */,
527+
&error);
528+
request =
529+
mock_server_receives_legacy_hello (server, "{'loadBalanced': true}");
530+
mock_server_replies_simple (request, NON_LB_HELLO);
531+
request_destroy (request);
532+
BSON_ASSERT (!future_get_bool (future));
533+
future_destroy (future);
534+
535+
ASSERT_ERROR_CONTAINS (error,
536+
MONGOC_ERROR_CLIENT,
537+
123,
538+
"Driver attempted to initialize in load balancing "
539+
"mode, but the server does not support this mode");
540+
541+
mongoc_uri_destroy (uri);
542+
mongoc_client_destroy (client);
543+
mock_server_destroy (server);
544+
}
545+
436546
static int
437547
skip_if_not_loadbalanced (void)
438548
{
@@ -495,4 +605,12 @@ test_loadbalanced_install (TestSuite *suite)
495605
NULL /* ctx */,
496606
skip_if_not_loadbalanced,
497607
test_framework_skip_if_no_failpoint);
608+
609+
TestSuite_AddMockServerTest (suite,
610+
"/loadbalanced/handshake_sends_loadbalanced",
611+
test_loadbalanced_handshake_sends_loadbalanced);
612+
TestSuite_AddMockServerTest (
613+
suite,
614+
"/loadbalanced/handshake_rejects_non_loadbalanced",
615+
test_loadbalanced_handshake_rejects_non_loadbalanced);
498616
}

0 commit comments

Comments
 (0)