Skip to content

Client Backpressure - #1918

Merged
stIncMale merged 29 commits into
mainfrom
backpressure
Sep 17, 2026
Merged

stIncMale merged 29 commits into
mainfrom
backpressure

Conversation

@stIncMale

@stIncMale stIncMale commented Mar 21, 2026 •

Copy link
Copy Markdown
Member

How to include main changes into backpressure

Rebase backpressure on top of main when there are no outstanding PRs for backpressure that are being reviewed, because this leads to GitHub closing the PRs.

See #1917 (comment) for more details.

How to deal with TODOs

TODO-BACKPRESSURE is the tag we use to leave TODOs in PRs for the backpressure branch that must be addressed before the current PR is merged in main. When we are leaving such a comment, and we know who should be responsible for addressing it, we should add the name of that engineer in the comment (for example, @stIncMale uses TODO-BACKPRESSURE Valentin for the TODOs he should address).

JAVA-5942, JAVA-6019, JAVA-6261

Comment thread driver-core/src/main/com/mongodb/MongoException.java
Comment thread driver-core/src/main/com/mongodb/MongoException.java
Comment thread driver-core/src/main/com/mongodb/MongoException.java
Comment thread driver-core/src/main/com/mongodb/MongoClientSettings.java
@evergreen-ci-prod

Copy link
Copy Markdown

There is an existing patch(es) for this commit SHA:

Please note that the status that is posted is not in the context of this PR but rather the (latest) existing patch and that may affect some tests that may depend on the particular PR. If your tests do not rely on any PR-specific values (like base or head branch name) then your tests will report the same status. If you would like a patch to run in the context of this PR and abort the other(s), comment 'evergreen retry'.

@stIncMale

stIncMale commented Jun 3, 2026 •

Copy link
Copy Markdown
Member Author

The latest Evergreen build for this PR did succeed.

Judging from a build result in a different PR that targets the backpressure branch, I suspect that some tests started failing without driver-side code changes (without even the specifications submodule changes). So I am rerunning the build here, to see how it goes. Update: it failed, and I left a PR comment that we'll need to address.

Comment thread driver-core/src/main/com/mongodb/MongoSocksProxyException.java
stIncMale and others added 25 commits September 17, 2026 11:05
- Deprioritize sharded clusters on any error, all other topologies only on SystemOverloadedError.
- Pass ClusterType to updateCandidate so onAttemptFailure can distinguish topology types.
- Add retryable reads prose tests 3.1 and 3.2.
- Change ServerSelectionSelectionTest to use BaseCluster server selection chain.

JAVA-6105
JAVA-6021
JAVA-6074
---------
Co-authored-by: Valentin Kovalenko <valentin.male.kovalenko@gmail.com>
Co-authored-by: Ross Lawley <ross.lawley@gmail.com>
- Add enableOverloadRetargeting boolean option to MongoClientSettings and ConnectionString to allow
  the driver to route requests to a different replica set member on retries when the previously
  used server is overloaded
- Add prose test 3.3 to verify that overload errors are retried on the same server when retargeting
  is disabled

JAVA-6167
---------

Co-authored-by: Ross Lawley <ross.lawley@gmail.com>
Introduce `sleepAsync`, `CommonExecutor`, `AsyncClientExecutor`

Notable changes:

- `MongoThreadPoolExecutor`/`MongoScheduledThreadPoolExecutor` - the executors we should eventually use everywhere internally (see https://jira.mongodb.org/browse/JAVA-6109), because they make sure uncaught task failures are propagated to the `UncaughtExceptionHandler`.
- `RetryPolicy.Decision.RetryAttemptInfo.getBackoff` - allows `RetryPolicy` to require the immediate next attempt to be delayed.
- `ThreadUtil.sleep`/`sleepAsync` - allows sleeping in `RetryingSyncSupplier`/`RetryingAsyncCallbackSupplier` based on the `RetryAttemptInfo.getBackoff`.
- `StreamFactoryFactory.getExecutor` - exposes the I/O executor used by `Stream`s to the rest of the `MongoClient` components.
- `AsyncClientExecutor` - allows to schedule a task using the aforementioned I/O executor, which saves us from creating another thread pool per `MongoClient`, essentially duplicating the I/O executor.
- `CommonExecutor` - provides the scheduling functionality when the I/O executor is not a `ScheduledThreadPoolExecutor` at the cost of a single new thread per class loader.

`AsyncClientExecutor` and `CommonExecutor` should eventually manage all internal computational resources (see https://jira.mongodb.org/browse/JAVA-4930).

JAVA-6240
- Extend SpecRetryPolicy so the overload sub-policy can borrow the write policy's error propagation logic independently of includeWrite(), enabling runCommand's client-backpressure rules without pulling in unwanted write-retry decisions.
- Split CommandReadOperation into an abstract base plus a concrete runCommand subclass that composes overload-only retries gated on retryReads && retryWrites; explain operations continue to use the base with no retry.

JAVA-6294
- Wrap CommandCursor / AsyncCommandCursor getMore in the SpecRetryPolicy
  overload-retry loop, gated by retryReads and propagated as a read command per
  client-backpressure, so any read cursor (find, aggregate, listCollections,
  listIndexes, changeStream) and the bulk-write result cursor participates in
  the overload-retry loop when iterating.
- Threads retryReads / maxAdaptiveRetries through to cursor construction sites,
  including ClientBulkWriteOperation whose result-cursor getMore is a read at
  the wire level despite the parent being a write.
- Extend the overload sub-policy with sessionScopeUpdatesSuspended so a nested
  retry loop (cursor getMore invoked inside another retry supplier such as the
  bulk-write cursor exhaust under RetryControl.doWhileDisabled) does not open,
  mutate, or close the parent's still-open command execution scope on the
  session.
- Remove the JAVA-5956 skip for the getMore-retried-backpressure unified test
  and adds coverage prose tests for the bulk-write cursor's getMore under
  overload retry, non-overload propagation, and retryReads=false.

JAVA-6296
- Implements overload-only retry (gated on retryWrites) for the write commands that previously dispatched with no retry wrapper: createIndexes, dropIndexes, create/drop/rename collection, aggregate with $out/$merge, and the search-index commands.
- Removes the JAVA-5956 skips that hid these commands from the unified client-backpressure suite, and adds prose tests (not part of the spec suite) covering the commands that have no unified test coverage.

JAVA-6308
JAVA-6119
JAVA-6124
JAVA-5956
Co-authored-by: Viacheslav Babanin <frest0512@gmail.com>

---------

Co-authored-by: Viacheslav Babanin <frest0512@gmail.com>
- Send backpressure: "2" in handshake.
- Add MongoDB 9.0 to Evergreen version matrix.
- Add baseBackoffMS override prose test (Test 5).
- Support server-supplied baseBackoffMS override for overload backoff.

JAVA-6238
JAVA-6255
…or` (#2056)

Non-terminated global threads are a problem as described in https://jira.mongodb.org/browse/JAVA-6291, https://jira.mongodb.org/browse/JAVA-5643. We know that there is at least one user who suffers from it and has a [workaround|#2029]. That workaround handles only the global thread in `PowerOfTwoBufferPool`, and will break when we release backpressure with another global thread in the `CommonExecutor`.

We temporarily stopped using `CommonExecutor` in `DefaultAsyncClientExecutor`, and use its own single-thread scheduler instead. We pay by sometimes creating a new thread per instance of `MongoClient`, but the aforementioned user workaround continues to work.

When we do https://jira.mongodb.org/browse/JAVA-6291, which will fix the problem in both `PowerOfTwoBufferPool` and `CommonExecutor`, we will change `DefaultAsyncClientExecutor` back to using `CommonExecutor`.

JAVA-6292
stIncMale and others added 2 commits September 17, 2026 11:37
We retry everything we must according to the spec, except for `killCursors`. Despite the specification requiring us to retry it, other drivers did not implement retries for this command, neither did the Java driver. The decision/spec will be reevaluated. For now we have https://jira.mongodb.org/browse/JAVA-6309.
…h the `main` branch (#2060)

Rebasing `backpressure` on top of `main` did not achieve that.
@stIncMale
stIncMale merged commit f0bc4cb into main Sep 17, 2026
202 of 282 checks passed
@stIncMale
stIncMale deleted the backpressure branch September 17, 2026 20:01
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.

5 participants