Skip to content

Commit b76cbf9

Browse files
authored
DRIVERS-2798 Drivers do not gossip $clusterTime on SDAM commands (#1735)
1 parent 75027a8 commit b76cbf9

File tree

2 files changed

+37
-7
lines changed

2 files changed

+37
-7
lines changed

source/sessions/driver-sessions.md

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,11 @@ with sessions.
9090

9191
Any network exception writing to or reading from a socket (e.g. a socket timeout or error).
9292

93+
**SDAM**
94+
95+
An abbreviated form of "Server Discovery and Monitoring", specification defined in
96+
[Server Discovery and Monitoring Specification](../server-discovery-and-monitoring/server-discovery-and-monitoring.md).
97+
9398
## Specification
9499

95100
Drivers currently have no concept of a session. The driver API will be expanded to provide a way for applications to
@@ -710,7 +715,8 @@ expiration.
710715

711716
## Gossipping the cluster time
712717

713-
Drivers MUST gossip the cluster time when connected to a deployment that uses cluster times.
718+
Drivers MUST gossip the cluster time when connected to a deployment that uses cluster times. However, drivers MUST NOT
719+
gossip cluster time on SDAM commands.
714720

715721
Gossipping the cluster time is a process in which the driver participates in distributing the logical cluster time in a
716722
deployment. Drivers learn the current cluster time (from a particular server's perspective) in responses they receive
@@ -722,7 +728,7 @@ received from a server.
722728

723729
### Receiving the current cluster time
724730

725-
Drivers MUST examine all responses from the server commands to see if they contain a top level field named
731+
Drivers MUST examine all non-SDAM responses from the server commands to see if they contain a top level field named
726732
`$clusterTime` formatted as follows:
727733

728734
```typescript
@@ -748,8 +754,9 @@ not participate in the comparison.
748754

749755
### Sending the highest seen cluster time
750756

751-
Whenever a driver sends a command to a server it MUST include the highest seen cluster time in a top level field called
752-
`$clusterTime`, in the same format as it was received in (but see Gossipping with mixed server versions below).
757+
Whenever a driver sends a non-SDAM command to a server it MUST include the highest seen cluster time in a top level
758+
field called `$clusterTime`, in the same format as it was received in (but see Gossipping with mixed server versions
759+
below).
753760

754761
### How to compute the `$clusterTime` to send to a server
755762

@@ -791,6 +798,15 @@ the command. A server supports `$clusterTime` when the `maxWireVersion` >= 6.
791798

792799
This supports the (presumably short lived) scenario where not all servers have been upgraded to 3.6.
793800

801+
### Do not gossip on SDAM commands
802+
803+
Drivers MUST NOT gossip cluster time on SDAM commands. In earlier versions of this spec, drivers did gossip cluster time
804+
on SDAM commands, however it was discovered that doing so provides little benefit and can result in a loss of
805+
availability. For example, if the driver attempts to connect to a member of a different replica set, the driver can end
806+
up with an invalid cluster time. Worse, this invalid cluster time may remain the highest for an indefinite time since
807+
clocks between different clusters are not synced. This results in all operations failing until the application is
808+
restarted. To fix this issue we decided it was more robust to stop gossiping on SDAM commands altogether.
809+
794810
## Test Plan
795811

796812
See the [README](tests/README.md) for tests.
@@ -918,6 +934,7 @@ has risks that do not justify the potential guaranteed `ServerSession` allocatio
918934

919935
## Changelog
920936

937+
- 2025-02-24: Drivers MUST NOT gossip $clusterTime on SDAM commands.
921938
- 2024-05-08: Migrated from reStructuredText to Markdown.
922939
- 2017-09-13: If causalConsistency option is omitted assume true
923940
- 2017-09-16: Omit session ID when opening and authenticating a connection

source/sessions/tests/README.md

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,6 @@ This test applies to drivers with session pools.
4949

5050
### 3. `$clusterTime` in commands
5151

52-
- Turn `heartbeatFrequencyMS` up to a very large number.
5352
- Register a command-started and a command-succeeded APM listener. If the driver has no APM support, inspect
5453
commands/replies in another idiomatic way, such as monkey-patching or a mock server.
5554
- Send a `ping` command to the server with the generic `runCommand` method.
@@ -58,8 +57,7 @@ This test applies to drivers with session pools.
5857
- Record the `$clusterTime`, if any, in the reply passed to the command-succeeded APM listener.
5958
- Send another `ping` command.
6059
- Assert that `$clusterTime` in the command passed to the command-started listener, if any, equals the `$clusterTime` in
61-
the previous server reply. (Turning `heartbeatFrequencyMS` up prevents an intervening heartbeat from advancing the
62-
`$clusterTime` between these final two steps.)
60+
the previous server reply.
6361

6462
Repeat the above for:
6563

@@ -238,8 +236,23 @@ and configure a `MongoClient` with default options.
238236
- Attempt to send a write command to the server (e.g., `insertOne`) with the explicit session passed in
239237
- Assert that a client-side error is generated indicating that sessions are not supported
240238

239+
### 20. Drivers do not gossip `$clusterTime` on SDAM commands.
240+
241+
- Skip this test when connected to a deployment that does not support cluster times
242+
- Create a client, C1, directly connected to a writable server and a small heartbeatFrequencyMS
243+
- `c1 = MongoClient(directConnection=True, heartbeatFrequencyMS=10)`
244+
- Run a ping command using C1 and record the `$clusterTime` in the response, as `clusterTime`.
245+
- `clusterTime = c1.admin.command({"ping": 1})["$clusterTime"]`
246+
- Using a separate client, C2, run an insert to advance the cluster time
247+
- `c2.test.test.insert_one({"advance": "$clusterTime"})`
248+
- Next, wait until the client C1 processes the next pair of SDAM heartbeat started + succeeded events.
249+
- If possible, assert the SDAM heartbeats do not send `$clusterTime`
250+
- Run a ping command using C1 and assert that `$clusterTime` sent is the same as the `clusterTime` recorded earlier.
251+
This assertion proves that C1's `$clusterTime` was not advanced by gossiping through SDAM.
252+
241253
## Changelog
242254

255+
- 2025-02-24: Test drivers do not gossip $clusterTime on SDAM.
243256
- 2024-05-08: Migrated from reStructuredText to Markdown.
244257
- 2019-05-15: Initial version.
245258
- 2021-06-15: Added snapshot-session tests. Introduced legacy and unified folders.

0 commit comments

Comments
 (0)