Skip to content

Commit e73f9f0

Browse files
committed
PYTHON-5947 Trim the operation telemetry comments and docstrings
Several of these grew while answering review questions and ended up explaining spec history or restating the code. Cut each to the invariant a reader needs.
1 parent 6212e9a commit e73f9f0

5 files changed

Lines changed: 32 additions & 85 deletions

File tree

pymongo/_otel.py

Lines changed: 14 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -75,10 +75,9 @@
7575
class _UnresolvedTracingOptions(TypedDict):
7676
"""The ``MongoClient`` ``tracing`` option as validated from user input.
7777
78-
``query_text_max_length`` is None when the user set no value, which is
79-
distinct from an explicit 0: None leaves the environment variable free to
80-
supply a length, 0 turns ``db.query.text`` off outright. Short-lived, since
81-
:func:`_resolve_tracing_options` runs while the client is being built.
78+
``query_text_max_length`` is None when unset, which is distinct from an
79+
explicit 0: None lets the environment variable supply a length, 0 turns
80+
``db.query.text`` off.
8281
"""
8382

8483
enabled: bool
@@ -88,9 +87,8 @@ class _UnresolvedTracingOptions(TypedDict):
8887
class TracingOptions(TypedDict):
8988
"""The ``MongoClient`` ``tracing`` option as a client holds it.
9089
91-
Both fields have been through :func:`_resolve_tracing_options`, so they
92-
account for the two environment variables and need no further
93-
interpretation: ``query_text_max_length`` is an int of 0 or more.
90+
:func:`_resolve_tracing_options` has folded in the environment variables,
91+
so ``query_text_max_length`` is an int of 0 or more.
9492
"""
9593

9694
enabled: bool
@@ -226,22 +224,8 @@ def _build_query_summary(command_name: str, dbname: str, collection: Optional[st
226224
return f"{command_name} {dbname}"
227225

228226

229-
# db.operation.name is the command name for nearly every operation, so `_Op`
230-
# values (which are the wire names) carry straight through. These are the
231-
# exceptions the spec's covered operations table names differently.
232-
#
233-
# "dropCollection" and "createCollection" are known deviations: their commands
234-
# are "drop" and "create", and the table departs from its own command-name rule
235-
# for no stated reason. The spec is expected to correct them, at which point
236-
# both entries here go away, but the change alters an exported attribute value
237-
# and so has to land on a major version boundary, in step with the other
238-
# drivers and the spec's own fixtures.
239-
#
240-
# "dropSearchIndexes" is ours, not the spec's: the command really is the
241-
# singular "dropSearchIndex" and only our `_Op` member is plural.
242-
#
243-
# Operations absent from the table (rename, whose command is "renameCollection")
244-
# have no agreed cross-driver name to match and keep their `_Op` value.
227+
# Spec operation names that differ from our `_Op` values. "dropCollection" and
228+
# "createCollection" contradict the spec's own command-name rule, unresolved.
245229
_OPERATION_NAME_OVERRIDES = {
246230
"drop": "dropCollection",
247231
"create": "createCollection",
@@ -302,29 +286,18 @@ def start_command_span(
302286
) -> Optional[Span]:
303287
"""Start and return a CLIENT-kind span for a server command, or None.
304288
305-
Returns None in two cases. With tracing off the call is a no-op. With a
306-
sensitive command it is not: the span is suppressed, mirroring the
307-
redaction applied to logs, but the current operation span is still
308-
backfilled from it, since that span needs the namespace and summary even
309-
when the command itself gets no span.
310-
311-
One span per wire-protocol message, so a retried operation produces one per
312-
attempt. The span takes whichever operation span is current as its parent,
313-
but is returned rather than made current itself, so nothing else nests
314-
inside it. The caller holds it for the command's duration.
289+
Returns None when tracing is off, and for a sensitive command, which still
290+
backfills the current operation span before being suppressed. One span per
291+
wire-protocol message, returned rather than made current, so nothing nests
292+
inside it.
315293
"""
316294
if not _is_tracing_enabled(tracing_options):
317295
return None
318296

319297
collection = _extract_collection_name(command_name, dbname, cmd)
320-
# Backfill the operation span's name/namespace/summary from the command built
321-
# inside it. Before the sensitive-command return below, since the operation
322-
# span needs those attributes even when the command gets no span. This runs
323-
# once per attempt rather than once per operation: an attempt that fails
324-
# before building a command never reaches here, so a retry can be where the
325-
# operation span first learns its namespace. Repeating it costs a few
326-
# attribute writes and is otherwise a no-op, since every attempt of one
327-
# operation carries the same namespace.
298+
# Runs per attempt, not per operation: an attempt that fails before building
299+
# a command never reaches here, so a retry may be where the span learns its
300+
# namespace.
328301
current_operation = _CURRENT_OPERATION_NAME.get()
329302
if current_operation is not None:
330303
current_span = trace.get_current_span()

pymongo/asynchronous/cursor_base.py

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -175,11 +175,8 @@ async def _die_lock(self) -> None:
175175
# ___init__ did not run to completion (or at all).
176176
return
177177

178-
# Before the cleanup below rather than after: this ends the span of the
179-
# operation that created the cursor, which has already completed, while
180-
# the cleanup sends killCursors under a separate operation span of its
181-
# own. A failure cleaning up belongs to that span, not to a find that
182-
# succeeded.
178+
# Before the cleanup, which sends killCursors under its own operation
179+
# span: a failure there belongs to that span, not to a find that succeeded.
183180
self._end_operation_telemetry()
184181
cursor_id, address = self._prepare_to_die(already_killed)
185182
await self._collection.database.client._cleanup_cursor_lock(

pymongo/asynchronous/mongo_client.py

Lines changed: 7 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1909,9 +1909,8 @@ async def _run_operation(
19091909
that executes the operation on a given connection.
19101910
:param address: Optional address when sending a message
19111911
to a specific server, used for getMore.
1912-
:param operation_telemetry: The operation span created by the calling
1913-
cursor (see ``AsyncCursor._refresh``), or None. Passed down so the
1914-
command spans of this send nest under it.
1912+
:param operation_telemetry: The calling cursor's operation span, or None,
1913+
so this send's command spans nest under it.
19151914
"""
19161915
if operation.conn_mgr:
19171916
server = await self._select_server(
@@ -2018,13 +2017,8 @@ async def _retry_internal(
20182017
:param is_run_command: If this is a runCommand operation, defaults to False
20192018
:param is_aggregate_write: If this is a aggregate operation with a write, defaults to False.
20202019
:param operation_id: Stable operation id shared across retries, defaults to None
2021-
:param operation_telemetry: An operation span the caller created and will
2022-
end itself, defaults to None. Only ``AsyncCursor`` passes one (see
2023-
``AsyncCursor._refresh``): its span has to survive send paths that
2024-
bypass this method, so the cursor ends it rather than this call.
2025-
Given a span, this method neither creates nor ends one and only
2026-
makes the caller's current for the duration of the call; given
2027-
None, it creates a span and ends it before returning.
2020+
:param operation_telemetry: A cursor's operation span, which this call
2021+
makes current but neither creates nor ends, defaults to None.
20282022
20292023
:return: Output of the calling func()
20302024
"""
@@ -2074,9 +2068,7 @@ async def _retryable_read(
20742068
:param is_run_command: If this is a runCommand operation, defaults to False.
20752069
:param is_aggregate_write: If this is a aggregate operation with a write, defaults to False.
20762070
:param operation_id: Stable operation id shared across retries, defaults to None
2077-
:param operation_telemetry: An operation span the caller created and will
2078-
end itself, defaults to None. See ``_retry_internal``, which this
2079-
forwards to.
2071+
:param operation_telemetry: As for ``_retry_internal``, defaults to None.
20802072
"""
20812073

20822074
# Ensure that the client supports retrying on reads and there is no session in
@@ -3008,10 +3000,8 @@ def __init__(
30083000
if operation_id is None:
30093001
operation_id = _generate_op_id_or_none(self._client._event_listeners)
30103002
self._operation_id = operation_id
3011-
# One span covers every attempt. With nothing passed in, create the
3012-
# span here and end it in run(). With a span passed in (a cursor's,
3013-
# which has to outlive this object), the caller keeps ownership and
3014-
# run() only makes it current.
3003+
# With nothing passed in, create the span here and end it in run(); with
3004+
# a span passed in, the caller owns it and run() only makes it current.
30153005
self._owns_telemetry = operation_telemetry is None
30163006
if self._owns_telemetry:
30173007
operation_telemetry = _operation_telemetry_or_none(

pymongo/synchronous/cursor_base.py

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -175,11 +175,8 @@ def _die_lock(self) -> None:
175175
# ___init__ did not run to completion (or at all).
176176
return
177177

178-
# Before the cleanup below rather than after: this ends the span of the
179-
# operation that created the cursor, which has already completed, while
180-
# the cleanup sends killCursors under a separate operation span of its
181-
# own. A failure cleaning up belongs to that span, not to a find that
182-
# succeeded.
178+
# Before the cleanup, which sends killCursors under its own operation
179+
# span: a failure there belongs to that span, not to a find that succeeded.
183180
self._end_operation_telemetry()
184181
cursor_id, address = self._prepare_to_die(already_killed)
185182
self._collection.database.client._cleanup_cursor_lock(

pymongo/synchronous/mongo_client.py

Lines changed: 7 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1904,9 +1904,8 @@ def _run_operation(
19041904
that executes the operation on a given connection.
19051905
:param address: Optional address when sending a message
19061906
to a specific server, used for getMore.
1907-
:param operation_telemetry: The operation span created by the calling
1908-
cursor (see ``Cursor._refresh``), or None. Passed down so the
1909-
command spans of this send nest under it.
1907+
:param operation_telemetry: The calling cursor's operation span, or None,
1908+
so this send's command spans nest under it.
19101909
"""
19111910
if operation.conn_mgr:
19121911
server = self._select_server(
@@ -2013,13 +2012,8 @@ def _retry_internal(
20132012
:param is_run_command: If this is a runCommand operation, defaults to False
20142013
:param is_aggregate_write: If this is a aggregate operation with a write, defaults to False.
20152014
:param operation_id: Stable operation id shared across retries, defaults to None
2016-
:param operation_telemetry: An operation span the caller created and will
2017-
end itself, defaults to None. Only ``Cursor`` passes one (see
2018-
``Cursor._refresh``): its span has to survive send paths that
2019-
bypass this method, so the cursor ends it rather than this call.
2020-
Given a span, this method neither creates nor ends one and only
2021-
makes the caller's current for the duration of the call; given
2022-
None, it creates a span and ends it before returning.
2015+
:param operation_telemetry: A cursor's operation span, which this call
2016+
makes current but neither creates nor ends, defaults to None.
20232017
20242018
:return: Output of the calling func()
20252019
"""
@@ -2069,9 +2063,7 @@ def _retryable_read(
20692063
:param is_run_command: If this is a runCommand operation, defaults to False.
20702064
:param is_aggregate_write: If this is a aggregate operation with a write, defaults to False.
20712065
:param operation_id: Stable operation id shared across retries, defaults to None
2072-
:param operation_telemetry: An operation span the caller created and will
2073-
end itself, defaults to None. See ``_retry_internal``, which this
2074-
forwards to.
2066+
:param operation_telemetry: As for ``_retry_internal``, defaults to None.
20752067
"""
20762068

20772069
# Ensure that the client supports retrying on reads and there is no session in
@@ -2997,10 +2989,8 @@ def __init__(
29972989
if operation_id is None:
29982990
operation_id = _generate_op_id_or_none(self._client._event_listeners)
29992991
self._operation_id = operation_id
3000-
# One span covers every attempt. With nothing passed in, create the
3001-
# span here and end it in run(). With a span passed in (a cursor's,
3002-
# which has to outlive this object), the caller keeps ownership and
3003-
# run() only makes it current.
2992+
# With nothing passed in, create the span here and end it in run(); with
2993+
# a span passed in, the caller owns it and run() only makes it current.
30042994
self._owns_telemetry = operation_telemetry is None
30052995
if self._owns_telemetry:
30062996
operation_telemetry = _operation_telemetry_or_none(

0 commit comments

Comments
 (0)