Skip to content

Commit 4a9defd

Browse files
authored
DRIVERS-2218: Clarify intended bounding of implicit session allocation and rework flaky prose test (#1157)
1 parent 67a56ad commit 4a9defd

File tree

1 file changed

+54
-40
lines changed

1 file changed

+54
-40
lines changed

source/sessions/driver-sessions.rst

Lines changed: 54 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ Driver Sessions Specification
33
=============================
44

55
:Spec Title: Driver Sessions Specification (See the registry of specs)
6-
:Spec Version: 1.9.0
6+
:Spec Version: 1.9.1
77
:Author: Robert Stam
88
:Spec Lead: A\. Jesse Jiryu Davis
99
:Advisory Group: Jeremy Mikola, Jeff Yemin, Samantha Ritter
@@ -12,7 +12,7 @@ Driver Sessions Specification
1212
:Status: Accepted (Could be Draft, Accepted, Rejected, Final, or Replaced)
1313
:Type: Standards
1414
:Minimum Server Version: 3.6 (The minimum server version this spec applies to)
15-
:Last Modified: 2022-01-28
15+
:Last Modified: 2022-03-24
1616

1717
.. contents::
1818

@@ -205,10 +205,12 @@ in such a way that new options can be added in a backward compatible way (it is
205205
acceptable for backward compatibility to be at the source level).
206206

207207
A ``ClientSession`` MUST be associated with a ``ServerSession`` at the time
208-
``startSession`` is called. As an implementation optimization drivers SHOULD reuse
208+
``startSession`` is called. As an implementation optimization drivers MUST reuse
209209
``ServerSession`` instances across multiple ``ClientSession`` instances subject
210210
to the rule that a server session MUST NOT be used by two ``ClientSession``
211-
instances at the same time (see the Server Session Pool section).
211+
instances at the same time (see the Server Session Pool section). Additionally,
212+
a ``ClientSession`` may only ever be associated with one ``ServerSession`` for
213+
its lifetime.
212214

213215
Drivers MUST report an error if sessions are not supported by the deployment
214216
(see How to Check Whether a Deployment Supports Sessions). This error MUST either
@@ -304,8 +306,8 @@ This property returns the ``SessionOptions`` that were used to start this
304306
sessionId
305307
---------
306308

307-
This property returns the session ID of this session. Note that if server
308-
sessions are pooled, different ``ClientSession`` instances will have the same session ID,
309+
This property returns the session ID of this session. Note that since ``ServerSessions``
310+
are pooled, different ``ClientSession`` instances can have the same session ID,
309311
but never at the same time.
310312

311313
advanceClusterTime
@@ -502,12 +504,12 @@ include a session ID in a ``KILLCURSORS`` command.
502504

503505
Sessions and Connections
504506
========================
505-
A driver MUST only obtain an implicit session after it successfully checks out a connection.
506-
This limits the number of implicit sessions to never exceed the maximum connection pool size.
507-
The motivation for this behavior is to prevent too many sessions from being created in a scenario
508-
where only a limited number are actually needed to execute operations (i.e. TooManyLogicalSessions error).
509507

510-
Explicit sessions MAY be changed to allocate a server session similarly, but it is not required.
508+
To reduce the number of ``ServerSessions`` created, the driver MUST only obtain an implicit session's
509+
``ServerSession`` after it successfully checks out a connection.
510+
A driver SHOULD NOT attempt to release the acquired session before connection check in.
511+
512+
Explicit sessions MAY be changed to allocate a server session similarly.
511513

512514
How to Check Whether a Deployment Supports Sessions
513515
===================================================
@@ -666,7 +668,9 @@ and implicit sessions.
666668
When wrapping commands in a ``$query`` field
667669
--------------------------------------------
668670

669-
If the driver is wrapping the command in a ``$query`` field in order to pass a readPreference to a mongos (see `ReadPreference and Mongos <./find_getmore_killcursors_commands.rst#readpreference-and-mongos>`_), the driver SHOULD NOT add the ``lsid`` as a top-level field, and MUST add the ``lsid`` as a field of the ``$query``
671+
If the driver is wrapping the command in a ``$query`` field for non-OP_MSG messages in order to pass a readPreference to a
672+
mongos (see `ReadPreference and Mongos <./find_getmore_killcursors_commands.rst#readpreference-and-mongos>`_),
673+
the driver SHOULD NOT add the ``lsid`` as a top-level field, and MUST add the ``lsid`` as a field of the ``$query``
670674

671675
.. code:: typescript
672676
@@ -781,12 +785,9 @@ In case of an error, the server response has the following format:
781785
782786
Drivers MUST ignore any errors returned by the ``endSessions`` command.
783787

784-
Drivers that do not implement a server session pool MUST run the ``endSessions``
785-
command when the ``ClientSession.endSession`` method is called. Drivers that do
786-
implement a server session pool SHOULD run the ``endSessions`` command once when
787-
the ``MongoClient`` instance is shut down. If the number of sessions is very large
788-
the ``endSessions`` command SHOULD be run multiple times to end 10,000 sessions at
789-
a time (in order to avoid creating excessively large commands).
788+
The ``endSessions`` command MUST be run once when the ``MongoClient`` instance is shut down.
789+
If the number of sessions is very large the ``endSessions`` command SHOULD be run
790+
multiple times to end 10,000 sessions at a time (in order to avoid creating excessively large commands).
790791

791792
When connected to a sharded cluster the ``endSessions`` command can be sent to any
792793
mongos. When connected to a replica set the ``endSessions`` command MUST be sent to
@@ -801,15 +802,15 @@ corresponding ``ServerSession``. However, starting a server session might requir
801802
round trip to the server (which can be avoided by generating the session ID
802803
locally) and ending a session requires a separate round trip to the server.
803804
Drivers can operate more efficiently and put less load on the server if they
804-
cache ``ServerSession`` instances for reuse. To this end drivers SHOULD
805+
cache ``ServerSession`` instances for reuse. To this end drivers MUST
805806
implement a server session pool containing ``ServerSession`` instances
806807
available for reuse. A ``ServerSession`` pool MUST belong to a ``MongoClient``
807808
instance and have the same lifetime as the ``MongoClient`` instance.
808809

809-
If a driver has a server session pool, then when a new ``ClientSession`` is started
810-
it MUST attempt to acquire a server session from the server session pool. See
811-
the algorithm below for the steps to follow when attempting to acquire a
812-
``ServerSession`` from the server session pool.
810+
When a new implicit ``ClientSession`` is started it MUST NOT attempt to acquire a server
811+
session from the server session pool immediately. When a new explicit ``ClientSession`` is started
812+
it MAY attempt to acquire a server session from the server session pool immediately.
813+
See the algorithm below for the steps to follow when attempting to acquire a ``ServerSession`` from the server session pool.
813814

814815
Note that ``ServerSession`` instances acquired from the server session pool might have as
815816
little as one minute left before becoming stale and being discarded server
@@ -825,18 +826,16 @@ to the hello and legacy hello commands. The smallest reported timeout is recorde
825826
``logicalSessionTimeoutMinutes`` property of the ``TopologyDescription``. See the
826827
Server Discovery And Monitoring specification for details.
827828

828-
If a driver has a server session pool, then when a ``ClientSession`` is ended it
829-
MUST return the server session to the server session pool. See the algorithm
830-
below for the steps to follow when returning a ``ServerSession`` instance to the server
829+
When a ``ClientSession`` is ended it MUST return the server session to the server session pool.
830+
See the algorithm below for the steps to follow when returning a ``ServerSession`` instance to the server
831831
session pool.
832832

833833
The server session pool has no maximum size. The pool only shrinks when a
834834
server session is acquired for use or discarded.
835835

836-
If a driver has a server session pool, then when a ``MongoClient`` instance is
837-
closed the driver MUST proactively inform the server that the pooled server
838-
sessions will no longer be used by sending one or more ``endSessions`` commands to the
839-
server.
836+
When a ``MongoClient`` instance is closed the driver MUST proactively inform the
837+
server that the pooled server sessions will no longer be used by sending one or
838+
more ``endSessions`` commands to the server.
840839

841840
The server session pool is modeled as a double ended queue. The algorithms
842841
below require the ability to add and remove ``ServerSession`` instances from the front of
@@ -1143,17 +1142,24 @@ Test Plan
11431142
* Attach a command started listener that collects each command's lsid
11441143
* Initiate the following concurrent operations
11451144

1146-
* insertOne
1147-
* deleteOne
1148-
* updateOne
1149-
* bulkWrite ``[ { updateOne } ]``
1150-
* findOneAndDelete
1151-
* findOneAndUpdate
1152-
* findOneAndReplace
1153-
* find
1145+
* ``insertOne({ }),``
1146+
* ``deleteOne({ }),``
1147+
* ``updateOne({ }, { $set: { a: 1 } }),``
1148+
* ``bulkWrite([{ updateOne: { filter: { }, update: { $set: { a: 1 } } } }]),``
1149+
* ``findOneAndDelete({ }),``
1150+
* ``findOneAndUpdate({ }, { $set: { a: 1 } }),``
1151+
* ``findOneAndReplace({ }, { a: 1 }),``
1152+
* ``find().toArray()``
1153+
1154+
* Wait for all operations to complete successfully
1155+
* Assert the following across at least 5 retries of the above test:
1156+
1157+
* Drivers MUST assert that exactly one session is used for all operations at least once across the retries of this test.
1158+
1159+
* Note that it's possible, although rare, for >1 server session to be used because the session is not released until after the connection is checked in.
1160+
1161+
* Drivers MUST assert that the number of allocated sessions is strictly less than the number of concurrent operations in every retry of this test. In this instance it would be less than (but NOT equal to) 8.
11541162

1155-
* Wait for all operations to complete
1156-
* Assert that all commands contain the same lsid
11571163

11581164

11591165
Tests that only apply to drivers that have not implemented OP_MSG and are still using OP_QUERY
@@ -1323,6 +1329,13 @@ is needed and, known it will be used, after connection checkout succeeds.
13231329
It is still possible that via explicit sessions or cursors, which hold on to the session they started with, a driver could over allocate sessions.
13241330
But those scenarios are extenuating and outside the scope of solving in this spec.
13251331

1332+
Why should drivers NOT attempt to release a serverSession before checking back in the operation's connection?
1333+
-------------------------------------------------------------------------------------------------------------
1334+
1335+
There are a variety of cases, such as retryable operations or cursor creating operations,
1336+
where a ``serverSession`` must remain acquired by the ``ClientSession`` after an operation is attempted.
1337+
Attempting to account for all these scenarios has risks that do not justify the potential guaranteed ``ServerSession`` allocation limiting.
1338+
13261339
Change log
13271340
==========
13281341

@@ -1353,3 +1366,4 @@ Change log
13531366
:2021-04-08: Adding in behaviour for load balancer mode.
13541367
:2020-05-26: Simplify logic for determining sessions support
13551368
:2022-01-28: Implicit sessions MUST obtain server session after connection checkout succeeds
1369+
:2022-03-24: ServerSession Pooling is required and clarifies session acquisition bounding

0 commit comments

Comments
 (0)