|
95 | 95 | _log_client_error, |
96 | 96 | _log_or_warn, |
97 | 97 | ) |
98 | | -from pymongo.message import _CursorAddress, _GetMore, _Query |
| 98 | +from pymongo.message import _CursorAddress, _GetMore, _Query, _randint |
99 | 99 | from pymongo.monitoring import ConnectionClosedReason, _EventListeners |
100 | 100 | from pymongo.operations import ( |
101 | 101 | DeleteMany, |
@@ -1837,6 +1837,8 @@ async def _select_server( |
1837 | 1837 | be pinned to a mongos server address. |
1838 | 1838 | - `address` (optional): Address when sending a message |
1839 | 1839 | to a specific server, used for getMore. |
| 1840 | + - `operation_id` (optional): Stable operation id shared across retries, |
| 1841 | + used for command monitoring. |
1840 | 1842 | """ |
1841 | 1843 | try: |
1842 | 1844 | topology = await self._get_topology() |
@@ -1932,6 +1934,7 @@ async def _run_operation( |
1932 | 1934 | async with operation.conn_mgr._lock: |
1933 | 1935 | async with _MongoClientErrorHandler(self, server, operation.session) as err_handler: # type: ignore[arg-type] |
1934 | 1936 | err_handler.contribute_socket(operation.conn_mgr.conn) |
| 1937 | + operation.conn_mgr.conn.op_id = _randint() |
1935 | 1938 | return await server.run_operation( |
1936 | 1939 | operation.conn_mgr.conn, |
1937 | 1940 | operation, |
@@ -2023,6 +2026,7 @@ async def _retry_internal( |
2023 | 2026 | :param retryable: If the operation should be retried once, defaults to None |
2024 | 2027 | :param is_run_command: If this is a runCommand operation, defaults to False |
2025 | 2028 | :param is_aggregate_write: If this is a aggregate operation with a write, defaults to False. |
| 2029 | + :param operation_id: Stable operation id shared across retries, defaults to None |
2026 | 2030 |
|
2027 | 2031 | :return: Output of the calling func() |
2028 | 2032 | """ |
@@ -2069,6 +2073,7 @@ async def _retryable_read( |
2069 | 2073 | (may not always be supported even if supplied), defaults to False |
2070 | 2074 | :param is_run_command: If this is a runCommand operation, defaults to False. |
2071 | 2075 | :param is_aggregate_write: If this is a aggregate operation with a write, defaults to False. |
| 2076 | + :param operation_id: Stable operation id shared across retries, defaults to None |
2072 | 2077 | """ |
2073 | 2078 |
|
2074 | 2079 | # Ensure that the client supports retrying on reads and there is no session in |
@@ -2112,6 +2117,7 @@ async def _retryable_write( |
2112 | 2117 | :param session: Client session we will use to execute write operation |
2113 | 2118 | :param operation: The name of the operation that the server is being selected for |
2114 | 2119 | :param bulk: bulk abstraction to execute operations in bulk, defaults to None |
| 2120 | + :param operation_id: Stable operation id shared across retries, defaults to None |
2115 | 2121 | """ |
2116 | 2122 | async with self._tmp_session(session) as s: |
2117 | 2123 | return await self._retry_with_session(retryable, func, s, bulk, operation, operation_id) |
@@ -2795,7 +2801,7 @@ def __init__( |
2795 | 2801 | self._server: Server = None # type: ignore |
2796 | 2802 | self._deprioritized_servers: list[Server] = [] |
2797 | 2803 | self._operation = operation |
2798 | | - self._operation_id = operation_id |
| 2804 | + self._operation_id = operation_id if operation_id is not None else _randint() |
2799 | 2805 | self._attempt_number = 0 |
2800 | 2806 | self._is_run_command = is_run_command |
2801 | 2807 | self._is_aggregate_write = is_aggregate_write |
@@ -3001,6 +3007,7 @@ async def _write(self) -> T: |
3001 | 3007 | is_mongos = False |
3002 | 3008 | self._server = await self._get_server() |
3003 | 3009 | async with self._client._checkout(self._server, self._session) as conn: |
| 3010 | + conn.op_id = self._operation_id |
3004 | 3011 | max_wire_version = conn.max_wire_version |
3005 | 3012 | sessions_supported = ( |
3006 | 3013 | self._session |
@@ -3040,6 +3047,7 @@ async def _read(self) -> T: |
3040 | 3047 | conn, |
3041 | 3048 | read_pref, |
3042 | 3049 | ): |
| 3050 | + conn.op_id = self._operation_id |
3043 | 3051 | if self._retrying and not self._retryable and not self._always_retryable: |
3044 | 3052 | self._check_last_error() |
3045 | 3053 | if self._retrying: |
|
0 commit comments