From f53ea06148757d6f334cbfb22530074467348083 Mon Sep 17 00:00:00 2001 From: Michael Morisi Date: Thu, 17 Jul 2025 09:35:10 -0400 Subject: [PATCH 1/7] DOCSP-51347: Server Selection --- source/connect/connection-options.txt | 1 + .../connection-options/server-selection.txt | 135 ++++++++++++++++++ source/includes/connect/ServerSelection.kt | 31 ++++ 3 files changed, 167 insertions(+) create mode 100644 source/connect/connection-options/server-selection.txt create mode 100644 source/includes/connect/ServerSelection.kt diff --git a/source/connect/connection-options.txt b/source/connect/connection-options.txt index 16be34bc..b84aa1bb 100644 --- a/source/connect/connection-options.txt +++ b/source/connect/connection-options.txt @@ -16,6 +16,7 @@ Specify Connection Options :maxdepth: 1 Network Compression + Server Selection Stable API Limit Server Execution Time Connection Pools diff --git a/source/connect/connection-options/server-selection.txt b/source/connect/connection-options/server-selection.txt new file mode 100644 index 00000000..1941bd62 --- /dev/null +++ b/source/connect/connection-options/server-selection.txt @@ -0,0 +1,135 @@ +.. _kotlin-sync-server-selection: + +========================== +Customize Server Selection +========================== + +.. contents:: On this page + :local: + :backlinks: none + :depth: 1 + :class: singlecol + +.. facet:: + :name: genre + :values: reference + +.. meta:: + :keywords: read preference, write + +Overview +-------- + +All MongoDB drivers follow a defined algorithm when selecting a server to read or write +from. By using the ``ClusterSettings`` property of a ``MongoClientSettings`` object, you can +customize this algorithm to choose the server that works best for your application. + +.. important:: + + Customizing the server selection algorithm might have unintended consequences, + such as degraded read or write performance. + +Default Algorithm +----------------- + +When the {+driver-short+} executes a read operation, it performs the following steps, +in order, to select a MongoDB deployment: + +1. Selects all servers that match the active read preference from the list of known servers. + +#. If at least one readable server exists, the driver calls the user-defined + server-selector function and passes in the list from the previous step. + +#. Applies the ``localThreshold`` connection setting to the list of + servers returned from the function. + +#. Selects a server at random from the servers still on the list and + executes the operation against this server. + +When the {+driver-short+} executes a write operation, it begins by selecting all writeable +servers, not just those that match the active read preference. The remaining steps are +identical. + +To learn more about the default server selection algorithm, which the driver follows +when you don't specify any custom server selection logic, see +:manual:`Server Selection Algorithm ` in the +{+mdb-server+} manual. + +Implementing Custom Server Selection Logic +------------------------------------------ + +You can implement your own custom server selection logic by creating a class that +implements the ``ServerSelector`` interface and overrides the ``select()`` method. The following +example shows a simple custom server selection class that selects servers with a ``type`` +value of ``ServerType.REPLICA_SET_SECONDARY``: + +.. literalinclude:: /includes/connect/ServerSelection.kt + :language: kotlin + :copyable: true + :start-after: // start-custom-selector + :end-before: // end-custom-selector + +You can then pass an instance of this class to your ``MongoClientSettings`` object by +using the ``applyToClusterSettings()`` method. The following example shows how to create +a ``MongoClient`` with an instance of the custom server selector from the preceding example: + +.. literalinclude:: /includes/connect/ServerSelection.kt + :language: kotlin + :copyable: true + :start-after: // start-selector + :end-before: // end-selector + +Using Settings to Configure Server Selection +-------------------------------------------- + +You can specify the following server selection settings in your ``MongoClient`` object or +in your connection URI: + +.. list-table:: + :widths: 30 70 + :header-rows: 1 + + * - Setting + - Description + + * - ``localThreshold`` + - | The latency window for server eligibility. If a server's round trip takes longer + | than the fastest server's round-trip time plus this value, the server isn't + | eligible for selection. + | + | **Data Type**: ``Integer`` + | **Default**: 15 milliseconds + | **Connection URI Example**: ``localThresholdMS=0`` + + * - ``readPreference`` + - | The client's default read-preference settings. For more information on read preference + options, see :manual:`Read Preference ` in the {+mdb-server+} manual. + | + | **Data Type**: `ReadPreference <{+core-api+}/ReadPreference.html>`__ + | **Default**: ``ReadPreference.primary()`` + | **Connection URI Example**: + + .. code-block:: none + :copyable: false + + readPreference=primaryPreferred + &maxStalenessSeconds=90 + &readPreferenceTags=dc:ny,rack:1 + + * - ``serverSelectionTimeout`` + - | The length of time the driver tries to select a server before timing out. + | + | **Data Type**: ``long`` + | **Default**: 30 seconds + | **Connection URI Example**: ``serverSelectionTimeoutMS=15000`` + +API Documentation +----------------- + +To learn more about the classes and methods used in this guide, see the following API +documentation: + +- `MongoClient <{+driver-api+}/-mongo-client/index.html>`__ +- `MongoClientSettings <{+core-api+}/MongoClientSettings.html>`__ +- `ServerSelector <{+core-api+}/ServerSelector.html>`__ +- `ReadPreference <{+core-api+}/ReadPreference.html>`__ \ No newline at end of file diff --git a/source/includes/connect/ServerSelection.kt b/source/includes/connect/ServerSelection.kt new file mode 100644 index 00000000..c56313b0 --- /dev/null +++ b/source/includes/connect/ServerSelection.kt @@ -0,0 +1,31 @@ +package org.example +import com.mongodb.ConnectionString +import com.mongodb.MongoClientSettings +import com.mongodb.connection.ClusterDescription +import com.mongodb.connection.ServerDescription +import com.mongodb.connection.ServerType +import com.mongodb.kotlin.client.MongoClient +import com.mongodb.selector.ServerSelector + +// start-custom-selector +class CustomServerSelector : ServerSelector { + override fun select(cluster: ClusterDescription): List { + return cluster.serverDescriptions.filter { it.type == ServerType.REPLICA_SET_SECONDARY } + } +} +// end-custom-selector + +fun main() { + // start-selector + val settings = MongoClientSettings.builder() + .applyConnectionString(ConnectionString("")) + .applyToClusterSettings { builder -> + builder.serverSelector(CustomServerSelector()) + } + .build() + + val mongoClient = MongoClient.create(settings) + // end-selector +} + + From 449e98aade256d79e5d6770bc96b2313234aba6b Mon Sep 17 00:00:00 2001 From: Michael Morisi Date: Thu, 17 Jul 2025 09:52:46 -0400 Subject: [PATCH 2/7] Fix --- source/connect/connection-options/server-selection.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/connect/connection-options/server-selection.txt b/source/connect/connection-options/server-selection.txt index 1941bd62..f665db32 100644 --- a/source/connect/connection-options/server-selection.txt +++ b/source/connect/connection-options/server-selection.txt @@ -131,5 +131,5 @@ documentation: - `MongoClient <{+driver-api+}/-mongo-client/index.html>`__ - `MongoClientSettings <{+core-api+}/MongoClientSettings.html>`__ -- `ServerSelector <{+core-api+}/ServerSelector.html>`__ +- `ServerSelector <{+core-api+}/selector/ServerSelector.html>`__ - `ReadPreference <{+core-api+}/ReadPreference.html>`__ \ No newline at end of file From c3d9175fab7c23a511bf1e7b3bab8a76cf3cc679 Mon Sep 17 00:00:00 2001 From: Michael Morisi Date: Fri, 18 Jul 2025 09:03:36 -0400 Subject: [PATCH 3/7] AS feedback --- .../connection-options/server-selection.txt | 30 +++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/source/connect/connection-options/server-selection.txt b/source/connect/connection-options/server-selection.txt index f665db32..cfe6fca2 100644 --- a/source/connect/connection-options/server-selection.txt +++ b/source/connect/connection-options/server-selection.txt @@ -15,7 +15,7 @@ Customize Server Selection :values: reference .. meta:: - :keywords: read preference, write + :keywords: read preference, write, server selection Overview -------- @@ -37,26 +37,26 @@ in order, to select a MongoDB deployment: 1. Selects all servers that match the active read preference from the list of known servers. -#. If at least one readable server exists, the driver calls the user-defined - server-selector function and passes in the list from the previous step. +#. If at least one readable server exists, calls the user-defined + server-selector function and passes in the list from the previous step #. Applies the ``localThreshold`` connection setting to the list of - servers returned from the function. + servers returned from the function #. Selects a server at random from the servers still on the list and - executes the operation against this server. + executes the operation against this server When the {+driver-short+} executes a write operation, it begins by selecting all writeable -servers, not just those that match the active read preference. The remaining steps are -identical. +servers from the list of known servers, not just those that match the active read preference. +The remaining steps are identical to the preceding list. To learn more about the default server selection algorithm, which the driver follows when you don't specify any custom server selection logic, see :manual:`Server Selection Algorithm ` in the {+mdb-server+} manual. -Implementing Custom Server Selection Logic ------------------------------------------- +Implement Custom Server Selection Logic +--------------------------------------- You can implement your own custom server selection logic by creating a class that implements the ``ServerSelector`` interface and overrides the ``select()`` method. The following @@ -69,9 +69,9 @@ value of ``ServerType.REPLICA_SET_SECONDARY``: :start-after: // start-custom-selector :end-before: // end-custom-selector -You can then pass an instance of this class to your ``MongoClientSettings`` object by -using the ``applyToClusterSettings()`` method. The following example shows how to create -a ``MongoClient`` with an instance of the custom server selector from the preceding example: +Use the ``applyToClusterSettings()`` method to pass an instance of this class to your +``MongoClientSettings``. The following example shows how to create +a ``MongoClient`` with an instance of the custom server selector class from the preceding example: .. literalinclude:: /includes/connect/ServerSelection.kt :language: kotlin @@ -79,8 +79,8 @@ a ``MongoClient`` with an instance of the custom server selector from the preced :start-after: // start-selector :end-before: // end-selector -Using Settings to Configure Server Selection --------------------------------------------- +Use Settings to Configure Server Selection +------------------------------------------ You can specify the following server selection settings in your ``MongoClient`` object or in your connection URI: @@ -119,7 +119,7 @@ in your connection URI: * - ``serverSelectionTimeout`` - | The length of time the driver tries to select a server before timing out. | - | **Data Type**: ``long`` + | **Data Type**: ``Long`` | **Default**: 30 seconds | **Connection URI Example**: ``serverSelectionTimeoutMS=15000`` From 7d062bae9f489c7e0e798df02510cae63458e6dd Mon Sep 17 00:00:00 2001 From: Michael Morisi Date: Fri, 25 Jul 2025 10:00:32 -0400 Subject: [PATCH 4/7] VK feedback --- .../connection-options/server-selection.txt | 24 +++++++++++-------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/source/connect/connection-options/server-selection.txt b/source/connect/connection-options/server-selection.txt index cfe6fca2..32cd6b90 100644 --- a/source/connect/connection-options/server-selection.txt +++ b/source/connect/connection-options/server-selection.txt @@ -29,29 +29,33 @@ customize this algorithm to choose the server that works best for your applicati Customizing the server selection algorithm might have unintended consequences, such as degraded read or write performance. -Default Algorithm ------------------ +Server Selection Algorithm +-------------------------- When the {+driver-short+} executes a read operation, it performs the following steps, in order, to select a MongoDB deployment: -1. Selects all servers that match the active read preference from the list of known servers. +1. Selects all servers from the list of known servers suitable for the requested + operation, barring those that the driver considers unavailable or problematic + + 1. For reads, selects all servers that match the active read preference + + #. For writes, selects all writeable servers -#. If at least one readable server exists, calls the user-defined - server-selector function and passes in the list from the previous step +#. Calls the user-defined server-selector function, if the user provides one, and passes in + the list from the previous step #. Applies the ``localThreshold`` connection setting to the list of servers returned from the function -#. Selects a server at random from the servers still on the list and - executes the operation against this server +#. Selects at most two random servers from the list of servers that match the + preceding criteria, then selects the server with fewer outstanding concurrent operations When the {+driver-short+} executes a write operation, it begins by selecting all writeable servers from the list of known servers, not just those that match the active read preference. The remaining steps are identical to the preceding list. -To learn more about the default server selection algorithm, which the driver follows -when you don't specify any custom server selection logic, see +To learn more about the MongoDB server selection algorithm, see :manual:`Server Selection Algorithm ` in the {+mdb-server+} manual. @@ -59,7 +63,7 @@ Implement Custom Server Selection Logic --------------------------------------- You can implement your own custom server selection logic by creating a class that -implements the ``ServerSelector`` interface and overrides the ``select()`` method. The following +implements the ``ServerSelector`` interface. The following example shows a simple custom server selection class that selects servers with a ``type`` value of ``ServerType.REPLICA_SET_SECONDARY``: From 08d20a55d136e19a8d4ef4fa896c04353094f1a6 Mon Sep 17 00:00:00 2001 From: Michael Morisi Date: Fri, 25 Jul 2025 10:16:12 -0400 Subject: [PATCH 5/7] Fix --- source/connect/connection-options/server-selection.txt | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/source/connect/connection-options/server-selection.txt b/source/connect/connection-options/server-selection.txt index 32cd6b90..8113b2ed 100644 --- a/source/connect/connection-options/server-selection.txt +++ b/source/connect/connection-options/server-selection.txt @@ -82,12 +82,14 @@ a ``MongoClient`` with an instance of the custom server selector class from the :copyable: true :start-after: // start-selector :end-before: // end-selector + :dedent: Use Settings to Configure Server Selection ------------------------------------------ -You can specify the following server selection settings in your ``MongoClient`` object or -in your connection URI: +You can specify the following server selection settings in your connection URI, +a ``MongoClientSettings`` object (for the ``localThreshold`` setting), or a ``ClusterSettings`` object +(for the ``readPreference`` and ``serverSelectionTimeout`` settings): .. list-table:: :widths: 30 70 From ff21ff672ea44611c032958a0b738fc966b0b658 Mon Sep 17 00:00:00 2001 From: Michael Morisi Date: Fri, 25 Jul 2025 15:56:36 -0400 Subject: [PATCH 6/7] fixes --- .../connection-options/server-selection.txt | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/source/connect/connection-options/server-selection.txt b/source/connect/connection-options/server-selection.txt index 8113b2ed..b0c1732d 100644 --- a/source/connect/connection-options/server-selection.txt +++ b/source/connect/connection-options/server-selection.txt @@ -87,9 +87,8 @@ a ``MongoClient`` with an instance of the custom server selector class from the Use Settings to Configure Server Selection ------------------------------------------ -You can specify the following server selection settings in your connection URI, -a ``MongoClientSettings`` object (for the ``localThreshold`` setting), or a ``ClusterSettings`` object -(for the ``readPreference`` and ``serverSelectionTimeout`` settings): +You can specify the following server selection settings in your ``MongoClient`` object or +in your connection URI: .. list-table:: :widths: 30 70 @@ -101,7 +100,8 @@ a ``MongoClientSettings`` object (for the ``localThreshold`` setting), or a ``Cl * - ``localThreshold`` - | The latency window for server eligibility. If a server's round trip takes longer | than the fastest server's round-trip time plus this value, the server isn't - | eligible for selection. + | eligible for selection. You can specify this setting to a ``MongoClientSettings`` object + in addition to the connection URI. | | **Data Type**: ``Integer`` | **Default**: 15 milliseconds @@ -109,7 +109,9 @@ a ``MongoClientSettings`` object (for the ``localThreshold`` setting), or a ``Cl * - ``readPreference`` - | The client's default read-preference settings. For more information on read preference - options, see :manual:`Read Preference ` in the {+mdb-server+} manual. + options, see :manual:`Read Preference ` in the {+mdb-server+} manual. + You can specify this setting to a ``ClusterSettings`` object in addition to the + connection URI. | | **Data Type**: `ReadPreference <{+core-api+}/ReadPreference.html>`__ | **Default**: ``ReadPreference.primary()`` @@ -124,6 +126,8 @@ a ``MongoClientSettings`` object (for the ``localThreshold`` setting), or a ``Cl * - ``serverSelectionTimeout`` - | The length of time the driver tries to select a server before timing out. + You can specify this setting to a ``ClusterSettings`` object in addition to the + connection URI. | | **Data Type**: ``Long`` | **Default**: 30 seconds From c40178ed99386e6930a79dfa66576a102d1e214d Mon Sep 17 00:00:00 2001 From: Michael Morisi Date: Fri, 25 Jul 2025 16:20:40 -0400 Subject: [PATCH 7/7] Fix --- source/connect/connection-options/server-selection.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/connect/connection-options/server-selection.txt b/source/connect/connection-options/server-selection.txt index b0c1732d..5726fc4b 100644 --- a/source/connect/connection-options/server-selection.txt +++ b/source/connect/connection-options/server-selection.txt @@ -100,7 +100,7 @@ in your connection URI: * - ``localThreshold`` - | The latency window for server eligibility. If a server's round trip takes longer | than the fastest server's round-trip time plus this value, the server isn't - | eligible for selection. You can specify this setting to a ``MongoClientSettings`` object + | eligible for selection. You can specify this setting to a ``ClusterSettings`` object in addition to the connection URI. | | **Data Type**: ``Integer`` @@ -110,7 +110,7 @@ in your connection URI: * - ``readPreference`` - | The client's default read-preference settings. For more information on read preference options, see :manual:`Read Preference ` in the {+mdb-server+} manual. - You can specify this setting to a ``ClusterSettings`` object in addition to the + You can specify this setting to a ``MongoClientSettings`` object in addition to the connection URI. | | **Data Type**: `ReadPreference <{+core-api+}/ReadPreference.html>`__