Skip to content

Conversation

@baileympearson
Copy link
Contributor

@baileympearson baileympearson commented Dec 2, 2025

DRIVERS-3239

Overview

This PR adds support for a new class of errors (SystemOverloadedError) to drivers' operation retry logic, as outlined in the design document.

Additionally, it includes a new argument to the MongoDB handshake (also defined in the design document).

Python will be second implementer.
Node implementation: mongodb/node-mongodb-native#4806

Testing

The testing strategy is two-fold:

  • Building off of Ezra's work to generate unified tests for retryable handshake errors, this PR generates unified tests to confirm that:

    • operations are retried using the new SystemOverloadedError label
    • operations are retried no more than 5 (current MAX_ATTEMPTS, as defined in the spec) times
  • Following Iris's work in DRIVERS-1934: withTransaction API retries too frequently #1851, this PR adds a prose test that ensures drivers apply exponential backoff in the retryability loop.

  • Update changelog.

  • Test changes in at least one language driver.

  • Test these changes against all server versions and topologies (including standalone, replica set, and sharded
    clusters).

@baileympearson baileympearson marked this pull request as ready for review December 2, 2025 18:59
@baileympearson baileympearson requested review from a team as code owners December 2, 2025 18:59
@baileympearson baileympearson requested review from jmikola and jyemin and removed request for a team December 2, 2025 18:59
@blink1073
Copy link
Member

It looks like you also need to bump the schema version:

source/client-backpressure/tests/backpressure-retry-loop.yml invalid
[
  {
    instancePath: '/tests/0/operations/3/expectError',
    schemaPath: '#/definitions/expectedError/type',
    keyword: 'type',
    params: { type: 'object' },
    message: 'must be object'
  }
]
 using schema v1.3
source/client-backpressure/tests/backpressure-retry-max-attempts.yml invalid
[
  {
    instancePath: '/tests/0/operations/1/expectError',
    schemaPath: '#/definitions/expectedError/type',
    keyword: 'type',
    params: { type: 'object' },
    message: 'must be object'
  }
]
 using schema v1.3source/client-backpressure/tests/backpressure-retry-loop.yml invalid
[
  {
    instancePath: '/tests/0/operations/3/expectError',
    schemaPath: '#/definitions/expectedError/type',
    keyword: 'type',
    params: { type: 'object' },
    message: 'must be object'
  }
]
 using schema v1.3
source/client-backpressure/tests/backpressure-retry-max-attempts.yml invalid
[
  {
    instancePath: '/tests/0/operations/1/expectError',
    schemaPath: '#/definitions/expectedError/type',
    keyword: 'type',
    params: { type: 'object' },
    message: 'must be object'
  }
]
 using schema v1.3

@blink1073
Copy link
Member

WIP Python implementation: mongodb/mongo-python-driver#2635

@blink1073
Copy link
Member

blink1073 commented Dec 3, 2025

All unified and prose tests are passing in the Python implementation.

Edit: we're still failing one unified test, "client.clientBulkWrite retries using operation loop", investigating...

Edit 2: we're all good now

Copy link
Contributor

@jyemin jyemin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I only reviewed the specification changes, not the pseudocode or tests. Those are best reviewed by implementers.

- This intentionally changes the behavior of CSOT which otherwise would retry an unlimited number of times within the
timeout to avoid retry storms.
5. If the previous error includes the `SystemOverloadedError` label, the client MUST apply exponential backoff according
to according to the following formula: `delayMS = j * min(maxBackoff, baseBackoff * 2^i)`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
to according to the following formula: `delayMS = j * min(maxBackoff, baseBackoff * 2^i)`
to the following formula: `delayMS = j * min(maxBackoff, baseBackoff * 2^i)`

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done


This specification expands the driver's retry ability to all commands, including those not currently considered
retryable such as updateMany, create collection, getMore, and generic runCommand. The new command execution method obeys
the following rules:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since the rules include all the deposits into the token bucket, consider adding withdrawals as well.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done


## Q&A

TODO
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Anything to add here, or just remove?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nothing yet .. I'll remove it for now. It can always be added back if there are items worth mentioning here.


## Changelog

- 2025-XX-XX: Initial version.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure how we handle the date... Is there an automation for this?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not that I know of. Usually the spec author fills it out before merging

I'll just leave this thread open to remind myself to add changelog dates before merging once all changes are completed.

to identify clients which do and do not support backpressure. Currently, this flag is unused but in the future the
server may offer different rate limiting behavior for clients that do not support backpressure.

##### Implementation notes
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
##### Implementation notes
#### Implementation notes


An error considered retryable by the [Retryable Writes Specification](../retryable-writes/retryable-writes.md).

#### Backpressure Error
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This spec should also get a changelog entry.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Copy link
Contributor Author

@baileympearson baileympearson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

submitting comments

operations:
-
object: *utilCollection
name: deleteMany
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, missed this one. I like your suggestion - done.

- This intentionally changes the behavior of CSOT which otherwise would retry an unlimited number of times within the
timeout to avoid retry storms.
5. If the previous error includes the `SystemOverloadedError` label, the client MUST apply exponential backoff according
to according to the following formula: `delayMS = j * min(maxBackoff, baseBackoff * 2^i)`
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done


This specification expands the driver's retry ability to all commands, including those not currently considered
retryable such as updateMany, create collection, getMore, and generic runCommand. The new command execution method obeys
the following rules:
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

The following pseudocode describes the overload retry policy:

```python
BASE_BACKOFF = 0.1
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I chose to leave it as-is; as the pseudocode is written in python and follows python conventions. Let me know if the clarified pseudocde works for you


## Changelog

- 2025-XX-XX: Initial version.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I removed the changelog

}
```

3. Execute the following command. Expect that the command errors. Measure the duration of the command execution.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've reworked the prose to be explicit about what the command is.

Copy link
Contributor

@matthewdale matthewdale left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good! 👍

5. A retry attempt consumes 1 token from the token bucket.
6. If the request is eligible for retry (as outlined in step 4), the client MUST apply exponential backoff according to
the following formula: `delayMS = j * min(maxBackoff, baseBackoff * 2^i)`
- `i` is the retry attempt number (starting with 0 for the first retry).
Copy link
Member

@sanych-sun sanych-sun Dec 19, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why we decided to have retry number start we 0? It makes the requirements confusing. Why don't we start with 1 and in fact we will have the same formula as for withTransaction:

delayMS = j * min(maxBackoff, baseBackoff * 2^(i-1))

With the only difference here we have 2 as the base for pow function, in convinientTransaction API we have 1.5

Copy link
Member

@sanych-sun sanych-sun Dec 19, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here is the formula from withTransaction:
jitter * min(BACKOFF_INITIAL * 1.5 ** (transactionAttempt - 1), BACKOFF_MAX)

Where transactionAttempt started with 0 and is being incremented AFTER the delay, but before executing the callback attempt. Which is also confusing... but in C# implementation we wait AFTER the attempt so it's more natural.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The phrasing, including "Retries start at 0", was just taken from the design. There's no need to keep it this way if it causes confusion.

I can adjust the phrasing to more closely align with the transaction spec, if that's preferable?

Copy link
Member

@sanych-sun sanych-sun Dec 19, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we use the following formula?
delayMS = j * min(maxBackoff, baseBackoff * 2^(i-1))

or

we can keep the formula as is, but adjust the baseBackoff :
delayMS = j * min(maxBackoff, baseBackoff * 2^i)
where baseBackoff is 50 instead of 100.

It produces the same results, but starts i with 1.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's fine to use any of those three formulas in individual driver implementations if it increases readability so long as they result in the same outputs. As far as reducing confusion, I can say it didn't substantially change my understanding of the formula.

+1 to Bailey changing the phrasing, which I think would suffice.

# Note: the values below have been scaled down by a factor of 1000 because
# Python's sleep API takes a duration in seconds, not milliseconds.
BASE_BACKOFF = 0.1 # 100ms
MAX_BACKOFF = 10 # 10s
Copy link
Member

@stIncMale stIncMale Dec 25, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The 100ms comment is helpful, because one can use it to find the same value in the prose part of the specification (though absolutely nothing prevents us from simply writing BASE_BACKOFF = 100ms).

However, the 10s comment is not helpful, because the prose part says 10000ms, and a reader won't find 10000ms in the pseudocode.

Suggested change
MAX_BACKOFF = 10 # 10s
MAX_BACKOFF = 10 # 10000ms

retry budget tracking, this counts as a success.
4. A retry attempt will only be permitted if:
1. The error has both the `SystemOverloadedError` and the `RetryableError` label.
2. We have not reached `MAX_ATTEMPTS`.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Judging both from the name of MAX_ATTEMPTS, and this sentence, a reader develops understanding that MAX_ATTEMPTS is the maximum number of attempts, which, includes the first attempt that is not a retry attempt. However, below, the specification says "Any retryable error is retried at most MAX_ATTEMPTS (default=5) times", which means that MAX_ATTEMPTS is the maximum number of retry attempts, implying that the maximum number of attempts is actually 6.

If MAX_ATTEMPTS is meant to specify the maximum number of retry attempts, let's name it accordingly: MAX_RETRY_ATTEMPTS.

1. The error has both the `SystemOverloadedError` and the `RetryableError` label.
2. We have not reached `MAX_ATTEMPTS`.
3. (CSOT-only): `timeoutMS` has not expired.
4. (`SystemOverloadedError` errors only) a token can be acquired from the token bucket.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Item 4.1 requires the SystemOverloadedError label to be present. The highlighted item 4.4 restricts itself to SystemOverloadedError errors only, but no other errors can possibly be considered because of item 4.11. Given this, why does item 4.4 has this restriction?

3. (CSOT-only): `timeoutMS` has not expired.
4. (`SystemOverloadedError` errors only) a token can be acquired from the token bucket.
- The value of `MAX_ATTEMPTS` is 5 and non-configurable.
- This intentionally changes the behavior of CSOT which otherwise would retry an unlimited number of times within the
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't these two sub-items about MAX_ATTEMPTS be under item 4.2, which talks about MAX_ATTEMPTS, rather than being under item 4.4, which talks about acquiring a token?

error and that it is retryable, including those not currently considered retryable such as updateMany, create
collection, getMore, and generic runCommand. The new command execution method obeys the following rules:

1. If the command succeeds on the first attempt, drivers MUST deposit `RETRY_TOKEN_RETURN_RATE` tokens.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The specification currently uses various terms to refer to the same thing1 when it talks about retry tokens (hopefully, I identified them all, but the author should do the exercise on his own to verify):

  • return, deposit, consume
  • deposit, return

We should pick a single term for each meaning and use it consistently. Having clear and consistent terminology is a necessity for clear communications, it also allows makes the specification searchable: if one wants to find all the places that talk about consuming retry tokens, one can search the page for a specific term. Currently, that is impossible.


1 Our specifications in general, as well as the official documentation the company produces, suffer from this significant issue.


#### Interaction with Existing Retry Behavior

The retryability API defined in this specification is separate from the existing retryability behaviors defined in the
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This sentence is the only place in the specification that suggests the specification defines "retryability API". Given that the specification does not define "retryability API", but it defines the "overload retry policy", which is what this sentence is talking about.

Interaction with Existing Retry Behavior
...
retryability behaviors

This specification already calls that behavior "policy", which means that the sentence should use the same term. It would have also been useful if we also named the existing policy, for example, the "read/write retry policy" (or, if we want to separate them, the "read retry policy" and the "write retry policy").

- Only retryable errors with the `SystemOverloadedError` label apply backoff and jitter.
- All retryable errors apply backoff if they also contain a `SystemOverloadedError` label. This includes:
- Errors defined as retryable in the retryable reads specification.
- Errors defined as retryable in the retryable writes specification.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's make "retryable reads specification" and "retryable writes specification" hyperlinks.

Comment on lines +120 to +121
- Only retryable errors with the `SystemOverloadedError` label apply backoff and jitter.
- All retryable errors apply backoff if they also contain a `SystemOverloadedError` label. This includes:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't these two sentences say the same? If yes, let's leave only one of them.

Comment on lines +121 to +124
- All retryable errors apply backoff if they also contain a `SystemOverloadedError` label. This includes:
- Errors defined as retryable in the retryable reads specification.
- Errors defined as retryable in the retryable writes specification.
- Errors with the `RetryableError` label.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given that a command may be retried either because of the read/write retry policy, or because of the overload retry policy, what does the i mean in the formula for delayMS? Is it the 1-based retry attempt number among all the retry attempts of a command, or only among the subset caused by the overload retry policy?

The answer to this question should be in the "Interaction with Existing Retry Behavior" section, not in the "Overload retry policy" section.

Comment on lines +121 to +126
- All retryable errors apply backoff if they also contain a `SystemOverloadedError` label. This includes:
- Errors defined as retryable in the retryable reads specification.
- Errors defined as retryable in the retryable writes specification.
- Errors with the `RetryableError` label.
- Any retryable error is retried at most MAX_ATTEMPTS (default=5) times, if any attempts has failed with a
`SystemOverloadedError`.
Copy link
Member

@stIncMale stIncMale Dec 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The "RetryableError label" section above says "An error is considered retryable if it includes the "RetryableError" label". After reading that, it is only reasonable to understand that a "retryable errror" is an error with the RetryableError label. However, in the selected items the specification seemingly uses the same term "retryable error" with a different meaning. This needs to be fixed.

I don't think that sections "RetryableError label", "SystemOverloadedError label" defining the terms "retryable error", "overloaded error" help a reader, neither do the the terms. Instead I propose the specification to always talk about an error having the RetryableError, SystemOverloadedError labels, which it already does in many places.

#1862 (comment) is related, but different.

Comment on lines +125 to +126
- Any retryable error is retried at most MAX_ATTEMPTS (default=5) times, if any attempts has failed with a
`SystemOverloadedError`.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I fail to understand what this requirement means. For example, "Any retryable error is retried" is very confusing, since we are trying to execute a command, not trying to execute/produce an error. The current wording also implies that the retry attempts are counted per each specific error, which can't be true, as they are counter per, for example, an execution of a command.

Does the following express the intended meaning?

Once we encounter such a command execution error with the SystemOverloadedError label that it permits a retry attempt according to the overload retry policy, the number of retry attempts for the particular command execution becomes limited by MAX_ATTEMPTS regardless of which retry policy the previous or the future retry attempts are caused by.

If "yes", then let's change the wording.

Note that the above means a command may still be retried more than MAX_ATTEMPTS times in the presence of errors having the SystemOverloadedError label. For example, if a command was retried 6 times according to the read/write retry policy with CSOT, and the 6th retry attempt (it's a 1-based index) failed with an error having the SystemOverloadedError label.

Comment on lines +38 to +41
#### RetryableError label

An error is considered retryable if it includes the "RetryableError" label. This error label indicates that an operation
is safely retryable regardless of the type of operation, its metadata, or any of its arguments.
Copy link
Member

@stIncMale stIncMale Dec 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

crud/bulk-write.md also talks about a "retryable error", but means some thing very different from what "retryable error" means here.

  1. Let's not overload this term by re-defining it with a different meaning here, as overloaded terms introduce confusion and have no benefits.
    1.1. If a term has to be overloaded nonetheless, which I doubt, let's at the very least make the changes to crud/bulk-write.md necessary to reduce confusion.
  2. The term "retryable error" is also defined in transactions/transactions.md. Fortunately, the meaning there does not need to be clarified.

Comment on lines +84 to +86
This specification expands the driver's retry ability to all commands if the error indicates that it is both an overload
error and that it is retryable, including those not currently considered retryable such as updateMany, create
collection, getMore, and generic runCommand. The new command execution method obeys the following rules:
Copy link
Member

@stIncMale stIncMale Dec 28, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Intro

Our specifications, as well as the official documentation, do not use the terms "operation" and "command" clearly, and neither does the specification introduced by this PR: it uses the terms seemingly interchangeably, despite them having very different meanings1:

The concern

The overload retry policy seems to be specified as applied at the command level: execution of any command consists of up to (MAX_ATTEMPTS + 1) attempts (and the "If a command fails backpressure retries MAX_ATTEMPTS times, it MUST not be retried again" sentence in transactions/transactions.md supports this interpretation). Given that execution of an operation may consist of many command executions, the above may result in a really large total number of retry attempts of different commands per execution of an operation. Is this indeed intended? I have doubts.

We can take a look at what execution of a client bulk write operation includes, as an example demonstrating how many executions of different commands may constitute execution of an operation:

  • potentially connection establishment
    • execution of a hello command
    • potentially authentication (let's assume it's a SASL authentication)
      • execution of a saslStart command
      • execution of a saslContinue command
      • potentially more executions of a saslContinue command
  • execution of a bulkWrite command
  • execution of a getMore command
  • potentially more executions of a getMore command
    • and/or potentially execution of a killCursors command
  • potentially more executions of a bulkWrite command, if there are more batches
  • potentially more executions of a getMore command, if there are more batches
  • potentially reauthentication

I suspect, the retry attempts should be counted not per execution of a command, but somehow else. This, however, may further complicate already convoluted retry policies and implementations. Anyway,

  1. the specification should clarify the scope within which retry attempts caused by the overload retry policy are limited by MAX_ATTEMPTS;
  2. the specification should use the terms "operation", "command" such that they are appropriate and match the meaning outlined above, unless those outlined meanings are incorrect.

1 I am aware that when trying to outline what an operation and a command are, as well as to clarify their executions, I am saying things that are not explicitly stated in the specifications. However, without introducing a vocabulary it is impossible to communicate, so I have to do that, since the specifications failed to (or I failed to find where they do that, despite spending significant amount of time).

Comment on lines +84 to +86
This specification expands the driver's retry ability to all commands if the error indicates that it is both an overload
error and that it is retryable, including those not currently considered retryable such as updateMany, create
collection, getMore, and generic runCommand. The new command execution method obeys the following rules:
Copy link
Member

@stIncMale stIncMale Dec 28, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The overload retry policy applies to "all commands", requiring drivers to inspect the result of a command attempt. On the other hand, the client bulk write specification says "The result returned from the killCursors command MAY be ignored.". Let's clarify whether the drivers must apply the overload retry policy to killCursors, or if execution of that command should never contain more than one attempt.

Previously @baileympearson said the following in Slack about this: "Operations that clean up resources could be retried but seem less important, because resources will be pruned by the server automatically after their timeout expires server-side.".


#### Backpressure Error

An error considered retryable by the [Client Backpressure Specification](../client-backpressure/client-backpressure.md).
Copy link
Member

@stIncMale stIncMale Dec 28, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The client backpressure specification says that "an error is considered retryable if it includes the "RetryableError" label". So there, a command with the "RetryableError" label is called retryable error, but here, the same error is called "backpressure error". Not only we are proposed to have the "retryable error" term overloaded (see #1862 (comment)), but we are also proposed to have multiple terms ("retryable error", "backpressure error") referring to the same exact thing. We should fix this:

  • we should use a single term to refer to the same thing;
  • we should avoid overloading terms.

P.S. I won't be surprised if the intent here was to express that backpressure error is an error that has both the RetryableError and the SystemOverloadError labels. But that is definitely not what the specification currently expresses.

Comment on lines +562 to +566
enabled on the MongoClient, unless the server response has backpressure error labels applied.

In addition, drivers MUST NOT add the RetryableWriteError label to any error that occurs during a write command within a
transaction (excepting commitTransation and abortTransaction), even when retryWrites has been enabled on the
MongoClient, unless the server response has backpressure error labels applied.
Copy link
Member

@stIncMale stIncMale Dec 28, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This specification defines the term "backpressure error", not "backpressure error labels". Shouldn't these sentences (there are two that use "backpressure error labels") just say something like "unless the command fails with a backpressure error", "unless the error is a backpressure error"?

the `abortTransaction` and `commitTransaction` commands, as well as any read or write commands attempted during the
transaction.

If a command fails with backpressure labels and it includes `startTransaction:true`, the retried command MUST also
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"If a command fails with backpressure labels" - is it the same as saying that a command fails with a "backpressure error" defined above? If yes, then the specification should use that term.

Comment on lines +580 to +582
All commands in a transaction are subject to the
[Client Backpressure Specification](../client-backpressure/client-backpressure.md), and MUST be retried accordingly when
the appropriate error labels are added by the server. This includes the initial command with `startTransaction:true`,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's remove the "when the appropriate error labels are added by the server" part. This is just one of multiple conditions that must be met for a command to be retried according to the overload retry policy, and it is weird to mention one of them, while avoiding the rest (I am not proposing to reiterate all of them here).

Suggested change
All commands in a transaction are subject to the
[Client Backpressure Specification](../client-backpressure/client-backpressure.md), and MUST be retried accordingly when
the appropriate error labels are added by the server. This includes the initial command with `startTransaction:true`,
All commands in a transaction are subject to the
[Client Backpressure Specification](../client-backpressure/client-backpressure.md), and MUST be retried accordingly. This includes the initial command with `startTransaction:true`,

Comment on lines +1064 to +1068
Drivers SHOULD apply a majority write concern when retrying commitTransaction to guard against a transaction being
applied twice.

Drivers SHOULD NOT modify the write concern on commit transaction commands when retrying a backpressure error, since we
are sure that the transaction has not been applied.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we know whether the transaction has or has not been applied. If, for example, in the scenario below step 4 fails with a backpressure error, it is obviously false that the transaction has not been applied.

I think, this change should be reverted.

Copy link
Member

@stIncMale stIncMale left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Notes for myself:

  • The last reviewed commit is 1b7f6df.
  • I reviewed only the changes in .md files, and do not plan to review the tests.
  • I have not re-reviewed the pseudocode illustrating the overload retry policy. I will do that after us settling on the requirements expressed in the prose part of the specification.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

10 participants