Skip to content

v1: client (CXX-3237, CXX-3238)#1559

Merged
eramongodb merged 16 commits intomongodb:masterfrom
eramongodb:cxx-abi-v1-client
Jan 14, 2026
Merged

v1: client (CXX-3237, CXX-3238)#1559
eramongodb merged 16 commits intomongodb:masterfrom
eramongodb:cxx-abi-v1-client

Conversation

@eramongodb
Copy link
Copy Markdown
Contributor

@eramongodb eramongodb commented Jan 9, 2026

Resolves CXX-3237 and CXX-3238 for the v1::client component.


Some fixes and improvements to CXX-3236 include:

  • Changed v1::client::client()'s options parameter from T const& -> T to permit moving the APM callbacks (unlike v_noabi which requires copies due to T const&).
  • Move the copy SMF deletions for v1::client inline within the class definition.
  • Fixed v1::client::watch() overloads so the v1::change_stream::options parameter is consistently T const& (a few were T despite no ownership transfers).

Due to acyclic-but-mutual-dependencies between the client, pool, client_session, and database components, some functions are left unimplemented and marked with // TODO: <component> (CXX-3237) comments. These comments will be addressed by upcoming associated component PRs. However, the refactored implementation of v_noabi::client mirrors the upcoming equivalent v1 implementations for v1::client and may be used as a preview/reference of the upcoming v1 implementation. Note that a stub for v1::client_session::options::~options() is required by MSVC to satisfy the definition(s) of v1::client::watch() (similar to the out-of-line virtual dtor definition requirement for CXX-3236; this does not affect other compilers).


For consistency with other refactored v_noabi components, the conversion helpers for v_noabi::options::* required by v_noabi::client are relocated and renamed to *::internal::to_mongoc(). There is some code duplication between the v_noabi and v1 implementation in order to avoid making intermediate copies that would be required by v_noabi <-> v1 conversions due to T const& parameter types. We can consider adding rvalue-ref overloads to allow opting-into a more efficient implementation (i.e. ownership transfer of APM callbacks), but I've opted not to do this for now.

Note the updated v_noabi tests for v_noabi::client and v_noabi::pool are due to the relocation of the tls_options data member out of v_noabi::client::impl. This data member appears to have been motivated by the (old) mock tests which assumed the lifetime of v_noabi::string::view_or_value::terminated()-owning strings for TLS options will be extended by the client object. This behavior is AFAIK not observable by the public API and is therefore removed in favor of a temporary , though the view-or-value behavior is preserve in the return value of v_noabi::options::tls::internal::to_mongoc().


For consistency with scoped_bson::operator+=(), rather than ignoring return values, calls to BSON_APPEND_*() instead throw undocumented std::logic_error exceptions to indicate contract violations. This only affects the "comment" field (no BCON_VALUE() for bson_value_t) and the "startAtOperationTime" field (BCON_TIMESTAMP() has incorrect parameter types).


v_noabi::options::client inherits the v_noabi <-> v1 key vault client (and pool) conversion problem described in #1551, due to the .auto_encryption_opts() field exposing the key vault client field. Therefore, it is given from_v1()/to_v1() overloads in a manner similar to v_noabi::options::auto_encryption.

However, v_noabi::client does not inherit this problem: the associated key vault client being stored by the mongoc library as mongoc_client_t*, not by the mongocxx library as v1::client*. Because the stored key vault client is not exposed by the v_noabi::client (or v1::client) public API (e.g. there is no .auto_encryption_opts().key_vault_client() -> v1::client*), the associated key vault client only needs to outlive the v_noabi::client (as usual) and use the mongoc_client_t managed by the underlying mongoc_client_t object. This is similar to how v_noabi::index_view and v_noabi::search_index_view store mongoc_client_t* rather than v1::client*; this pattern has been extended to v_noabi::database and v_noabi::collection for consistency.

@eramongodb eramongodb requested a review from kevinAlbs January 9, 2026 15:52
@eramongodb eramongodb self-assigned this Jan 9, 2026
@eramongodb eramongodb requested a review from a team as a code owner January 9, 2026 15:52
/// @param mongodb_uri
/// A MongoDB URI representing the connection parameters
/// @param options
/// Additional options that cannot be specified via the mongodb_uri
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// Additional options that cannot be specified via the mongodb_uri
/// Additional client options

Suggest removing "cannot be specified". Some TLS options can be specified in either the URI (e.g. tlsCertificateKeyFile) or options (e.g. pem_file).

Comment on lines +111 to +114
/// Creates a new client connection to MongoDB.
///
MONGOCXX_ABI_EXPORT_CDECL() ~client();

client(client const&) = delete;
client& operator=(client const&) = delete;
/// @param mongodb_uri
/// A MongoDB URI representing the connection parameters
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// Creates a new client connection to MongoDB.
///
MONGOCXX_ABI_EXPORT_CDECL() ~client();
client(client const&) = delete;
client& operator=(client const&) = delete;
/// @param mongodb_uri
/// A MongoDB URI representing the connection parameters
/// Creates a new client to MongoDB.
///
/// @param mongodb_uri
/// A MongoDB URI

Suggest removing "connection" to avoid confusing with a network connection (of which a client has many).

struct to_mongoc_type {
std::list<bsoncxx::v_noabi::string::view_or_value> string_owner;

mongoc_ssl_opt_t opt;
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mongoc_ssl_opt_t is conditionally defined in libmongoc. This may need to restore a #if MONGOCXX_SSL_IS_ENABLED() check to successfully build against a C driver built without SSL support.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch.

Further investigation also revealed cases where the v1::client test cases were not prepared for code paths triggered by an ENABLE_SSL=OFF configuration. Updated accordingly.

The internal call to v1::uri::tls() has been moved out of the ifdef blocks for consistent invocation count by mocked test cases.

mocks.client_destroy->interpose([&](mongoc_client_t* ptr) -> void {
if (ptr) {
if (ptr != kv_client_id) {
FAIL_CHECK("unspected mongoc_client_t");
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
FAIL_CHECK("unspected mongoc_client_t");
FAIL_CHECK("unexpected mongoc_client_t");

Copy link
Copy Markdown
Contributor Author

@eramongodb eramongodb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Excuse the delay. GCC on RHEL 8 ARM64 does not seem to like the client_mocks_type pattern. For reasons unclear, it specifically dislikes the "auto_encryption_opts" test case and segfaults during destruction. Stacktrace points to std::lock_guard<std::mutex> lock(_active_instances_lock); in mock<T>::destroy_active_instance(); enabling ASAN suppresses the issue (!?); UBSAN reports out-of-alignment access of a parent mock object from _parent->destroy_active_instance() in the mock<T>::instance dtor (???); Clang does not exhibit this behavior. Therefore, I suspect this may be a GCC compiler codegen bug specific to ARM64(?), but could not find any relevant bug reports. Dynamically allocation appears to be a viable workaround, so the "auto_encryption_opts" test case uses std::unique_ptr<client_mocks_type> mocks_owner; instead of the usual client_mocks_type mocks;.

struct to_mongoc_type {
std::list<bsoncxx::v_noabi::string::view_or_value> string_owner;

mongoc_ssl_opt_t opt;
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch.

Further investigation also revealed cases where the v1::client test cases were not prepared for code paths triggered by an ENABLE_SSL=OFF configuration. Updated accordingly.

The internal call to v1::uri::tls() has been moved out of the ifdef blocks for consistent invocation count by mocked test cases.

Copy link
Copy Markdown
Collaborator

@kevinAlbs kevinAlbs left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Latest changes LGTM. Some linked tasks are failing in the db-aggregate-write-readPreference test, but I expect those are unrelated. Reported CXX-3400.

@eramongodb eramongodb merged commit 55a6bfc into mongodb:master Jan 14, 2026
18 of 21 checks passed
@eramongodb eramongodb deleted the cxx-abi-v1-client branch January 14, 2026 15:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants