Skip to content

Commit

Permalink
DRIVERS-2327 NoWritesPerformed Retryable Writes Error Handling (#1297)
Browse files Browse the repository at this point in the history
  • Loading branch information
prestonvasquez committed Sep 1, 2022
1 parent eaec267 commit e4a5564
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 3 deletions.
7 changes: 5 additions & 2 deletions source/retryable-writes/retryable-writes.rst
Expand Up @@ -3,14 +3,14 @@ Retryable Writes
================

:Spec Title: Retryable Writes
:Spec Version: 1.8.0
:Spec Version: 1.8.1
:Author: Jeremy Mikola
:Lead: \A. Jesse Jiryu Davis
:Advisors: Robert Stam, Esha Maharishi, Samantha Ritter, and Kaloian Manassiev
:Status: Accepted
:Type: Standards
:Minimum Server Version: 3.6
:Last Modified: 2022-01-25
:Last Modified: 2022-08-30

.. contents::

Expand Down Expand Up @@ -409,6 +409,9 @@ error should be raised instead as the caller can infer that an attempt was made
and the second error is likely more relevant (with respect to the current
topology state).

If a retry attempt fails with an error labeled NoWritesPerformed, drivers MUST
return the original error.

Drivers MUST NOT attempt to retry a write command with the same transaction ID
more than once.

Expand Down
64 changes: 63 additions & 1 deletion source/retryable-writes/tests/README.rst
Expand Up @@ -353,7 +353,7 @@ and sharded clusters.
retryWrites=false to your connection string.

and the error code is 20.

**Note**: Drivers that rely on ``serverStatus`` to determine the storage engine
in use MAY skip this test for sharded clusters, since ``mongos`` does not report
this information in its ``serverStatus`` response.
Expand Down Expand Up @@ -395,10 +395,72 @@ and sharded clusters.

9. Disable the failpoint.

#. Test that drivers return the original error after encountering a
WriteConcernError with a RetryableWriteError label. This test MUST

1. be implemented by any driver that implements the Command Monitoring
specification,

2. only run against replica sets as mongos does not propagate the
NoWritesPerformed label to the drivers.

Additionally, this test requires drivers to set a fail point after an
``insertOne`` operation but before the subsequent retry. Drivers that are
unable to set a failCommand after the CommandSucceededEvent SHOULD use
mocking or write a unit test to cover the same sequence of events.


1. Create a client with ``retryWrites=true``.

2. Configure a fail point with error code ``91`` (ShutdownInProgress)::

db.adminCommand({
configureFailPoint: "failCommand",
mode: {times: 1},
data: {
writeConcernError: {
code: 91,
errorLabels: ["RetryableWriteError"],
},
failCommands: ["insert"],
},
});

3. Via the command monitoring CommandSucceededEvent, configure a fail point
with error code ``10107`` (NotWritablePrimary) and a NoWritesPerformed
label::

db.adminCommand({
configureFailPoint: "failCommand",
mode: {times: 1},
data: {
errorCode: 10107,
errorLabels: ["RetryableWriteError", "NoWritesPerformed"],
failCommands: ["insert"],
},
});

Drivers SHOULD only configure the ``10107`` fail point command if the the
succeeded event is for the ``91`` error configured in step 2.

4. Attempt an ``insertOne`` operation on any record for any database and
collection. For the resulting error, assert that the associated error code
is ``91``.

5. Disable the fail point::

db.adminCommand({
configureFailPoint: "failCommand",
mode: "off",
})

Changelog
=========

:2022-08-30: Add prose test verifying correct error handling for errors with
the NoWritesPerformed label, which is to return the original
error.

:2022-04-22: Clarifications to ``serverless`` and ``useMultipleMongoses``.

:2021-08-27: Add ``serverless`` to ``runOn``. Clarify behavior of
Expand Down

0 comments on commit e4a5564

Please sign in to comment.