From 8094bea1aab869c077d422131cd732228b66a26a Mon Sep 17 00:00:00 2001 From: rustagir Date: Tue, 1 Jul 2025 13:39:41 -0400 Subject: [PATCH 1/4] DOCSP-49971: csot cc --- source/connect/connection-options/csot.txt | 235 +++++++++++++++++- source/connect/specify-connection-options.txt | 83 +------ source/includes/connect/csot.go | 62 +++++ 3 files changed, 299 insertions(+), 81 deletions(-) create mode 100644 source/includes/connect/csot.go diff --git a/source/connect/connection-options/csot.txt b/source/connect/connection-options/csot.txt index bb90e174..2bcfa1e5 100644 --- a/source/connect/connection-options/csot.txt +++ b/source/connect/connection-options/csot.txt @@ -1,6 +1,239 @@ +.. _golang-timeout-setting: +.. _golang-csot: =========================== Limit Server Execution Time =========================== -.. TODO \ No newline at end of file +.. contents:: On this page + :local: + :backlinks: none + :depth: 2 + :class: singlecol + +.. facet:: + :name: genre + :values: reference + +.. meta:: + :keywords: error, blocking, thread, task, code example + +Overview +-------- + +In this guide, you can learn about the single timeout setting in the +{+driver-short+}, also known as the **client-side operation timeout (CSOT)**. + +When you use the {+driver-short+} to perform a server operation, you can also +limit the amount of time in which the server can finish the operation. +The timeout applies to all steps needed to complete the operation, +including server selection, connection checkout, and server-side +execution. When the timeout expires, the {+driver-short+} raises a +timeout exception. + +.. note:: Experimental Feature + + The CSOT feature is experimental and might change in future driver + releases. + +timeoutMS Option +---------------- + +To specify a timeout when connecting to a MongoDB deployment, set the +``timeoutMS`` connection option to the timeout length in milliseconds. You can +set the ``timeoutMS`` option in the following ways: + +- Calling the ``SetTimeout()`` method when + specifying options for your ``Client`` instance +- Setting the ``timeoutMS`` parameter in your connection string + +The following code examples set a client-level timeout of ``200`` milliseconds. +Select the :guilabel:`Client` or :guilabel:`Connection +String` tab to see the corresponding code. + +.. tabs:: + + .. tab:: MongoClientSettings + :tabid: mongoclientsettings + + .. literalinclude:: /includes/connect/csot.go + :language: go + :start-after: start-client-opts + :end-before: end-client-opts + :dedent: + :emphasize-lines: 1 + + .. tab:: Connection String + :tabid: connection-string + + .. literalinclude:: /includes/connect/csot.go + :language: go + :start-after: start-string + :end-before: end-string + :dedent: + +.. note:: Retries Under Timeout Specification + + If you set a timeout on your ``Client`` or in an operation-level + Context and the server returns a retryable error, the driver retries the + operation as many times as possible before the timeout expires. + + Once the timeout expires, the driver returns a timeout error. + See the Server manual for more information about :ref:`retryable + reads ` and :manual:`retryable writes + `. + +Accepted Timeout Values +~~~~~~~~~~~~~~~~~~~~~~~ + +The following table describes the timeout behavior corresponding to the +accepted values for ``timeoutMS``: + +.. list-table:: + :header-rows: 1 + :widths: 25 75 + + * - Value + - Behavior + + * - Positive integer + - Sets the timeout to use for operation completion. + + * - ``0`` + - Specifies that operations never time out. + + * - ``null`` or unset + - | Defers the timeout behavior to the following settings: + + - :manual:`waitQueueTimeoutMS ` + - :manual:`socketTimeoutMS ` + - :manual:`wTimeoutMS ` + - :manual:`maxTimeMS ` + + | These settings are deprecated and are ignored if you set ``timeoutMS``. + +If you specify the ``timeoutMS`` option, the driver automatically applies the +specified timeout to each server operation. + +Timeout Inheritance +~~~~~~~~~~~~~~~~~~~ + +By default, all ``Database``, ``Collection``, ``Session``, ``ChangeStream``, and +``Bucket`` instances elsewhere in your application inherit the +``Timeout`` option from ``Client`` if you do not set a different timeout +on specific operations in the operation's Context. + +If you set a timeout on a Context passed into an operation, the driver uses +that value for the operation. If you do not specify a Context timeout, +the operation Context derives the timeout from the ``Client`` instance. + +The following table describes how the timeout value is inherited at each level: + +.. list-table:: + :header-rows: 1 + :widths: 30 70 + + * - Level + - Inheritance Description + + * - Operation + - Takes the highest precedence and overrides the timeout + options that you set at any other level. + + * - Transaction + - Takes precedence over the timeout value that you set at the + client level. + + * - Client + - Applies to all databases, collections, sessions, transactions, and + operations within that client that do not otherwise specify a + Context timeout. + +For more information on overrides and specific options, see the following +:ref:`golang-csot-overrides` section. + +.. _golang-csot-overrides: + +Overrides +--------- + +The {+driver-short+} supports various levels of configuration to control the +behavior and performance of database operations. + +You can specify a ``timeoutMS`` option at a more specific level to override the +client-level configuration. The table in the preceding section describes +the levels at which you can specify a timeout setting. This allows you +to customize timeouts based on the needs of individual operations. + +The following example shows how to set an operation-level timeout in a +Context, which takes priority over the client-level timeout: + +.. literalinclude:: /includes/connect/csot.go + :language: go + :start-after: start-override + :end-before: end-override + :dedent: + :emphasize-lines: 9, 12 + +.. _go-csot-transaction: + +Transactions +~~~~~~~~~~~~ + +When you perform a transaction by using the `WithTransaction() +<{+api+}/mongo#Session.WithTransaction>`__ method, you can apply a +timeout to the transaction operations by setting a timeout within the +Context. + +The following code demonstrates how to set a Context timeout when +calling the ``WithTransaction()`` method to perform a transaction: + +.. literalinclude:: /includes/connect/csot.go + :language: go + :start-after: start-txn-context + :end-before: end-txn-context + :dedent: + :emphasize-lines: 1, 4 + +If you do not specify a Context timeout, the driver inherits the timeout +value set on the parent ``Client``. + +You can also pass Context timeouts to the following session +methods: + +- ``AbortTransaction()`` +- ``CommitTransaction()`` +- ``EndSession()`` + +To learn more about transactions, see the :ref:`golang-transactions` +guide. + +.. _go-csot-cursor: + +Cursors +------- + +Cursors offer configurable timeout settings when using the CSOT feature. You can +adjust cursor timeouts by passing Contexts that have timeout +specifications to `Cursor <{+api+}/mongo#Cursor>`__ methods. + +For operations that create cursors, the timeout setting can either cap the +lifetime of the cursor or be applied separately to the original +operation and all subsequent calls. + +For example, if you pass a Context timeout to the ``Cursor.Next()`` +method, the timeout applies to each action to fetch a result document. +If you pass a Context timeout to the ``Cursor.All()`` method, the +timeout applies to the entire lifetime of the cursor. + +To learn more about cursors, see the :ref:`golang-cursor` guide. + +API Documentation +----------------- + +To learn more about using timeouts with the {+driver-short+}, see the following +API documentation: + +- `ClientOptions <{+api+}/mongo/options#ClientOptions>`__ +- `SetTimeout() <{+api+}/mongo/options#ClientOptions.SetTimeout>`__ +- `Context.WithTimeout() `__ diff --git a/source/connect/specify-connection-options.txt b/source/connect/specify-connection-options.txt index 06cb5452..f675a6ba 100644 --- a/source/connect/specify-connection-options.txt +++ b/source/connect/specify-connection-options.txt @@ -56,7 +56,9 @@ default value, and a description of the option. - ``null`` - Specifies the number of milliseconds that a single operation run on the ``Client`` can take before returning a timeout error. Operations honor - this setting only if there is no deadline on the operation Context. + this setting only if there is no deadline on the operation + Context. To learn more about this option, see the :ref:`CSOT + ` guide. * - **connectTimeoutMS** - integer @@ -127,82 +129,3 @@ default value, and a description of the option. For a full list of connection options, see the `ClientOptions API documentation <{+api+}/mongo/options#ClientOptions>`__. - -.. _golang-timeout-setting: - -Single Timeout Setting ----------------------- - -You can set a single ``Timeout`` option on your ``Client`` instance to -specify the maximum amount of time that a single operation can take to -execute. - -Set a client-level timeout by calling the ``SetTimeout()`` method when -specifying options for your ``Client`` instance or by specifying the -``timeoutMS`` option in your connection URI. By default, all -``Database``, ``Collection``, ``Session``, ``ChangeStream``, and -``Bucket`` instances elsewhere in your application inherit the -``Timeout`` option from ``Client`` if you do not set a different timeout -on specific operations in the operation's Context. - -If you set a timeout on a Context passed into an operation, the driver uses -that value for the operation. If you do not specify a Context timeout, -the operation Context derives the timeout from the ``Client`` instance. - -.. note:: Retries under Timeout Specification - - If you set a timeout on your ``Client`` or in an operation-level - Context and the server returns a retryable error, the driver retries the - operation as many times as possible before the timeout expires. - - Once the timeout expires, the driver returns a timeout error. - See the Server manual for more information about :ref:`retryable - reads ` and :manual:`retryable writes - `. - -Timeout Examples -~~~~~~~~~~~~~~~~ - -This section provides examples that demonstrate different ways to set a -timeout in your application. - -Client Option -^^^^^^^^^^^^^ - -The following code shows how to set the ``Timeout`` option on a ``Client`` -by using the ``SetTimeout()`` method: - -.. code-block:: go - - opts := options.Client().SetTimeout(5 * time.Second) - client, err := mongo.Connect(opts) - -Connection String Option -^^^^^^^^^^^^^^^^^^^^^^^^ - -The following example shows how to set a single timeout by using the -``timeoutMS`` URI option. Then, the code executes an insert operation -that inherits the timeout: - -.. code-block:: go - :emphasize-lines: 1, 5 - - uri := "mongodb://user:pass@sample.host:27017/?timeoutMS=5000" - client, err := mongo.Connect(options.Client().ApplyURI(uri)) - - ... - coll.InsertOne(context.Background(), doc) - -Operation Timeout -^^^^^^^^^^^^^^^^^ - -The following example shows how to set an operation-level timeout in a -Context, which takes priority over a client-level timeout you might have -set: - -.. code-block:: go - - ctx, cancel := context.WithTimeout(context.TODO(), time.Second) - defer cancel() - - res, err := coll.InsertOne(ctx, bson.D{{"x", 2}}) diff --git a/source/includes/connect/csot.go b/source/includes/connect/csot.go new file mode 100644 index 00000000..171b03f1 --- /dev/null +++ b/source/includes/connect/csot.go @@ -0,0 +1,62 @@ +package main + +import ( + "context" + "log" + "time" + + "go.mongodb.org/mongo-driver/v2/bson" + "go.mongodb.org/mongo-driver/v2/mongo" + "go.mongodb.org/mongo-driver/v2/mongo/options" +) + +func main() { + + // start-client-opts + opts := options.Client().SetTimeout(200 * time.Millisecond) + client, err := mongo.Connect(opts) + // end-client-opts + // start-string + uri := "/?timeoutMS=200" + client, err := mongo.Connect(options.Client().ApplyURI(uri)) + // end-string + if err != nil { + log.Fatal(err) + } + + // start-override + opts = options.Client().SetTimeout(200 * time.Millisecond) + client, err = mongo.Connect(opts) + if err != nil { + log.Fatal(err) + } + + coll := client.Database("db").Collection("people") + + ctx, cancel := context.WithTimeout(context.TODO(), 300*time.Millisecond) + defer cancel() + + _, err = coll.InsertOne(ctx, bson.D{{"name", "Agnes Georgiou"}}) + // end-override + + session, err := client.StartSession() + if err != nil { + panic(err) + } + defer session.EndSession(context.TODO()) + + // start-txn-context + txnContext, cancel := context.WithTimeout(context.TODO(), 300*time.Millisecond) + defer cancel() + + result, err := session.WithTransaction(txnContext, func(ctx context.Context) (string, error) { + // Perform transaction operations + }) + // end-txn-context + + defer func() { + if err = client.Disconnect(context.TODO()); err != nil { + log.Fatal(err) + } + }() +} From c69bd2676071201db07c06af2d6744eefd65ad71 Mon Sep 17 00:00:00 2001 From: rustagir Date: Wed, 2 Jul 2025 14:21:23 -0400 Subject: [PATCH 2/4] MB PR fixes 1 --- source/connect/connection-options/csot.txt | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/source/connect/connection-options/csot.txt b/source/connect/connection-options/csot.txt index 2bcfa1e5..4df80eee 100644 --- a/source/connect/connection-options/csot.txt +++ b/source/connect/connection-options/csot.txt @@ -118,8 +118,7 @@ specified timeout to each server operation. Timeout Inheritance ~~~~~~~~~~~~~~~~~~~ -By default, all ``Database``, ``Collection``, ``Session``, ``ChangeStream``, and -``Bucket`` instances elsewhere in your application inherit the +By default, all operations in your application inherit the ``Timeout`` option from ``Client`` if you do not set a different timeout on specific operations in the operation's Context. @@ -217,8 +216,8 @@ Cursors offer configurable timeout settings when using the CSOT feature. You can adjust cursor timeouts by passing Contexts that have timeout specifications to `Cursor <{+api+}/mongo#Cursor>`__ methods. -For operations that create cursors, the timeout setting can either cap the -lifetime of the cursor or be applied separately to the original +For operations that create cursors, the timeout setting can either limit +the lifetime of the cursor or be applied separately to the original operation and all subsequent calls. For example, if you pass a Context timeout to the ``Cursor.Next()`` From 94bab280c332f82978ab79463bb5a80bf80bfcc5 Mon Sep 17 00:00:00 2001 From: rustagir Date: Thu, 3 Jul 2025 10:06:47 -0400 Subject: [PATCH 3/4] small wip --- source/includes/connect/csot.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/includes/connect/csot.go b/source/includes/connect/csot.go index 171b03f1..1b61ff22 100644 --- a/source/includes/connect/csot.go +++ b/source/includes/connect/csot.go @@ -41,7 +41,7 @@ func main() { session, err := client.StartSession() if err != nil { - panic(err) + log.Fatal(err) } defer session.EndSession(context.TODO()) From d9ed0c0a30e88612c0fcc28314195b21ca7d9a23 Mon Sep 17 00:00:00 2001 From: rustagir Date: Thu, 3 Jul 2025 10:08:27 -0400 Subject: [PATCH 4/4] small wip --- source/connect/connection-options/csot.txt | 11 +++++------ source/includes/connect/csot.go | 5 +---- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/source/connect/connection-options/csot.txt b/source/connect/connection-options/csot.txt index 4df80eee..5ccf15ea 100644 --- a/source/connect/connection-options/csot.txt +++ b/source/connect/connection-options/csot.txt @@ -61,16 +61,15 @@ String` tab to see the corresponding code. :start-after: start-client-opts :end-before: end-client-opts :dedent: - :emphasize-lines: 1 .. tab:: Connection String :tabid: connection-string - .. literalinclude:: /includes/connect/csot.go - :language: go - :start-after: start-string - :end-before: end-string - :dedent: + .. code-block:: go + :copyable: true + + uri := "/?timeoutMS=200" + client, err := mongo.Connect(options.Client().ApplyURI(uri)) .. note:: Retries Under Timeout Specification diff --git a/source/includes/connect/csot.go b/source/includes/connect/csot.go index 1b61ff22..4209d576 100644 --- a/source/includes/connect/csot.go +++ b/source/includes/connect/csot.go @@ -16,10 +16,7 @@ func main() { opts := options.Client().SetTimeout(200 * time.Millisecond) client, err := mongo.Connect(opts) // end-client-opts - // start-string - uri := "/?timeoutMS=200" - client, err := mongo.Connect(options.Client().ApplyURI(uri)) - // end-string + if err != nil { log.Fatal(err) }