PYTHON-5903 Retry attempts should share a single stable operation_id#2901
PYTHON-5903 Retry attempts should share a single stable operation_id#2901shrey-mongo wants to merge 22 commits into
Conversation
247b26f to
682dbac
Compare
|
Please fill out the pull request template completely. |
There was a problem hiding this comment.
Pull request overview
This PR ensures command-monitoring operation_id remains stable across retry attempts for retryable reads/writes and relevant cursor operations, improving APM correlation for a single logical operation.
Changes:
- Mint a single per-operation
operation_idin the retryable-operation wrapper and stamp it onto the checked-out connection for each attempt. - Thread the connection’s
op_idthrough pool/server command execution intocommand_runnerso published command-monitoring events use it. - Add sync + async integration tests that force multiple retries via
failCommandand assert all related command events share oneoperation_id.
Reviewed changes
Copilot reviewed 11 out of 11 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
tools/synchro.py |
Registers the new test file in the synchro conversion list. |
test/test_operation_id_retry.py |
Sync integration coverage asserting operation_id stability across retries (and no retry for non-retryable multi-writes). |
test/asynchronous/test_operation_id_retry.py |
Async equivalent of the retry operation_id stability tests. |
pymongo/synchronous/server.py |
Passes conn.op_id into cursor command execution for APM publishing. |
pymongo/synchronous/pool.py |
Adds Connection.op_id, forwards it into run_command, and clears it on check-in. |
pymongo/synchronous/mongo_client.py |
Mints/stabilizes per-operation ids across retries and stamps them on checked-out connections. |
pymongo/synchronous/command_runner.py |
Accepts/threads op_id through run_command / run_cursor_command into _run_command. |
pymongo/asynchronous/server.py |
Async counterpart: passes conn.op_id for cursor command execution. |
pymongo/asynchronous/pool.py |
Async counterpart: adds/forwards/clears op_id on connections. |
pymongo/asynchronous/mongo_client.py |
Async counterpart: stable per-operation id and per-attempt stamping onto connections. |
pymongo/asynchronous/command_runner.py |
Async counterpart: threads op_id through command execution to APM event publishing. |
|
Updated description to include full template |
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
|
There are merge conflicts, please resolve. |
5546477 to
75f4e21
Compare
|
I fixed the merge conflict and the typing error that was causing the workflow to fail |
1707aa0 to
63312b0
Compare
… into shrey-mongo/PYTHON-5903
I'm not sure if we need a changelog entry but maybe you intended to add one? May as well add one e.g. |
|
You're right, updated the changelog. |
PYTHON-5903: Retry attempts should share a single stable operation_id
Changes in this PR
Command-monitoring events carry an
operation_idto correlate the events of one logical operation. For single-document CRUD and cursor operations, each retry attempt got a differentoperation_id(it defaulted to the per-attemptrequest_id), so consumers couldn't group a retried operation's events. Bulk writes already shared one across batches._ClientConnectionRetryablemints theoperation_idonce per logical operation.pymongo/_op_id.pymodule holds anOP_IDContextVarand an_OpIdContextcontext manager._write/_readenter it around each attempt's command execution, so every attempt publishes the same id; on exit the previous value is restored.command_runner._run_commandfalls back toOP_ID.get()when no explicitop_idis passed (bulk write pass their own), and threads it to thepublish_command_*events and command logs.Noneand keep falling back torequest_id._handle_reauthsuppresses the in-flight id (_OpIdContext(None)) while re-authenticating, then restores it for the retried command.AsyncPeriodicExecutor._run()resetsOP_IDalongside_csot.reset_all()so executor tasks don't inherit an operation's id from their spawning context.Test Plan
test/asynchronous/test_operation_id_retry.pyforces multiple retries via afailCommandfailpoint across a read/write matrix and asserts all command events share oneoperation_idtest_async_contextvars_reset.pyto assertOP_IDis reset inside executor tasks, alongside the CSOT vars.Checklist
Checklist for Author
Checklist for Reviewer