From ac12b55e05a4687894fe6291a4c819a7ded4cdbf Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Wed, 2 Jul 2025 08:21:15 -0500 Subject: [PATCH 1/6] PYTHON-4780 Implement fast path for server selection with Primary --- pymongo/topology_description.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/pymongo/topology_description.py b/pymongo/topology_description.py index 29293b2314..34b340d0b7 100644 --- a/pymongo/topology_description.py +++ b/pymongo/topology_description.py @@ -324,6 +324,14 @@ def apply_selector( description = self.server_descriptions().get(address) return [description] if description else [] + # Primary selection fast path. + if self.topology_type == TOPOLOGY_TYPE.ReplicaSetWithPrimary and isinstance( + selector, TOPOLOGY_TYPE.Primary + ): + for sd in self._server_descriptions.values(): + if sd.server_type == SERVER_TYPE.RSPrimary: + return [sd] + selection = Selection.from_topology_description(self) # Ignore read preference for sharded clusters. if self.topology_type != TOPOLOGY_TYPE.Sharded: From f32a3a62c75b981b51af19bb82a5c917ef542226 Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Thu, 3 Jul 2025 09:31:01 -0500 Subject: [PATCH 2/6] PYTHON-4780 Implement fast path for server selection with Primary --- pymongo/topology_description.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pymongo/topology_description.py b/pymongo/topology_description.py index 34b340d0b7..fefc752ea9 100644 --- a/pymongo/topology_description.py +++ b/pymongo/topology_description.py @@ -34,7 +34,7 @@ from bson.objectid import ObjectId from pymongo import common from pymongo.errors import ConfigurationError, PyMongoError -from pymongo.read_preferences import ReadPreference, _AggWritePref, _ServerMode +from pymongo.read_preferences import Primary, ReadPreference, _AggWritePref, _ServerMode from pymongo.server_description import ServerDescription from pymongo.server_selectors import Selection from pymongo.server_type import SERVER_TYPE @@ -326,7 +326,7 @@ def apply_selector( # Primary selection fast path. if self.topology_type == TOPOLOGY_TYPE.ReplicaSetWithPrimary and isinstance( - selector, TOPOLOGY_TYPE.Primary + selector, Primary ): for sd in self._server_descriptions.values(): if sd.server_type == SERVER_TYPE.RSPrimary: From 07e0dca9a2fbdb0c86061bc2a21438f35c4361d7 Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Thu, 3 Jul 2025 09:38:49 -0500 Subject: [PATCH 3/6] fix zizmor --- .github/workflows/zizmor.yml | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/.github/workflows/zizmor.yml b/.github/workflows/zizmor.yml index c6237d2bda..785444be76 100644 --- a/.github/workflows/zizmor.yml +++ b/.github/workflows/zizmor.yml @@ -17,16 +17,5 @@ jobs: uses: actions/checkout@v4 with: persist-credentials: false - - name: Setup Rust - uses: actions-rust-lang/setup-rust-toolchain@fb51252c7ba57d633bc668f941da052e410add48 # v1 - - name: Get zizmor - run: cargo install zizmor - name: Run zizmor 🌈 - run: zizmor --format sarif . > results.sarif - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - name: Upload SARIF file - uses: github/codeql-action/upload-sarif@39edc492dbe16b1465b0cafca41432d857bdb31a # v3 - with: - sarif_file: results.sarif - category: zizmor + uses: zizmorcore/zizmor-action@1cc8f934e6fad1414fbfc420bd02b0c325d9daab # v1.11.0 From 7dfc3f11962f5bad854af0171ed6cc2caf501a83 Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Thu, 3 Jul 2025 09:40:42 -0500 Subject: [PATCH 4/6] fix zizmor --- .github/workflows/zizmor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/zizmor.yml b/.github/workflows/zizmor.yml index 785444be76..1d58c0d5fb 100644 --- a/.github/workflows/zizmor.yml +++ b/.github/workflows/zizmor.yml @@ -18,4 +18,4 @@ jobs: with: persist-credentials: false - name: Run zizmor 🌈 - uses: zizmorcore/zizmor-action@1cc8f934e6fad1414fbfc420bd02b0c325d9daab # v1.11.0 + uses: zizmorcore/zizmor-action@1c7106082dbc1753372e3924b7da1b9417011a21 From 746e8d5b75a0b22b0b84876032da2c0d4a315997 Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Thu, 3 Jul 2025 10:02:55 -0500 Subject: [PATCH 5/6] update test --- test/asynchronous/test_server_selection.py | 4 ++-- test/test_server_selection.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/test/asynchronous/test_server_selection.py b/test/asynchronous/test_server_selection.py index f98a05ee91..f570662b85 100644 --- a/test/asynchronous/test_server_selection.py +++ b/test/asynchronous/test_server_selection.py @@ -130,12 +130,12 @@ async def test_selector_called(self): test_collection = mongo_client.testdb.test_collection self.addAsyncCleanup(mongo_client.drop_database, "testdb") - # Do N operations and test selector is called at least N times. + # Do N operations and test selector is called at least N-1 times due to fast path. await test_collection.insert_one({"age": 20, "name": "John"}) await test_collection.insert_one({"age": 31, "name": "Jane"}) await test_collection.update_one({"name": "Jane"}, {"$set": {"age": 21}}) await test_collection.find_one({"name": "Roe"}) - self.assertGreaterEqual(selector.call_count, 4) + self.assertGreaterEqual(selector.call_count, 3) @async_client_context.require_replica_set async def test_latency_threshold_application(self): diff --git a/test/test_server_selection.py b/test/test_server_selection.py index aec8e2e47a..4384deac2b 100644 --- a/test/test_server_selection.py +++ b/test/test_server_selection.py @@ -130,12 +130,12 @@ def test_selector_called(self): test_collection = mongo_client.testdb.test_collection self.addCleanup(mongo_client.drop_database, "testdb") - # Do N operations and test selector is called at least N times. + # Do N operations and test selector is called at least N-1 times due to fast path. test_collection.insert_one({"age": 20, "name": "John"}) test_collection.insert_one({"age": 31, "name": "Jane"}) test_collection.update_one({"name": "Jane"}, {"$set": {"age": 21}}) test_collection.find_one({"name": "Roe"}) - self.assertGreaterEqual(selector.call_count, 4) + self.assertGreaterEqual(selector.call_count, 3) @client_context.require_replica_set def test_latency_threshold_application(self): From e5a0c846552d2828dae57ed4791ae47029a5b945 Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Thu, 3 Jul 2025 10:03:46 -0500 Subject: [PATCH 6/6] update readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 2acc0fc086..374fc3e4f3 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ a native Python driver for MongoDB, offering both synchronous and asynchronous A [gridfs](https://github.com/mongodb/specifications/blob/master/source/gridfs/gridfs-spec.md/) implementation on top of `pymongo`. -PyMongo supports MongoDB 4.0, 4.2, 4.4, 5.0, 6.0, 7.0, and 8.0. PyMongo follows [semantic versioning](https://semver.org/spec/v2.0.0.html) for its releases. +PyMongo supports MongoDB 4.0, 4.2, 4.4, 5.0, 6.0, 7.0, and 8.0. PyMongo follows [semantic versioning](https://semver.org/spec/v2.0.0.html) for its releases. ## Support / Feedback