Skip to content

Commit d51f38b

Browse files
committed
PYTHON-5846 Cache _should_log/_should_publish in short-lived telemetry classes; document why long-lived classes use properties
1 parent 57f4e50 commit d51f38b

1 file changed

Lines changed: 22 additions & 13 deletions

File tree

pymongo/_telemetry.py

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -228,10 +228,12 @@ def __init__(
228228

229229
@property
230230
def _should_publish(self) -> bool:
231+
"""Computed per-call because listener registration can change while the pool is open."""
231232
return self._publish and self._listeners is not None and self._listeners.enabled_for_cmap
232233

233234
@property
234235
def _should_log(self) -> bool:
236+
"""Computed per-call because logging level can be reconfigured at runtime."""
235237
return self._log and _CONNECTION_LOGGER.isEnabledFor(logging.DEBUG)
236238

237239
def _emit_log(self, message: _ConnectionStatusMessage, **extra: Any) -> None:
@@ -364,7 +366,15 @@ class _HeartbeatTelemetry:
364366
context, then :meth:`succeeded` or :meth:`failed` when the outcome is known.
365367
"""
366368

367-
__slots__ = ("_address", "_awaited", "_listeners", "_start", "_topology_id")
369+
__slots__ = (
370+
"_address",
371+
"_awaited",
372+
"_listeners",
373+
"_should_log",
374+
"_should_publish",
375+
"_start",
376+
"_topology_id",
377+
)
368378

369379
def __init__(
370380
self,
@@ -377,14 +387,10 @@ def __init__(
377387
self._address = address
378388
self._listeners = listeners
379389
self._awaited = awaited
380-
381-
@property
382-
def _should_publish(self) -> bool:
383-
return self._listeners is not None and self._listeners.enabled_for_server_heartbeat
384-
385-
@property
386-
def _should_log(self) -> bool:
387-
return _SDAM_LOGGER.isEnabledFor(logging.DEBUG)
390+
# Cached at construction: this object is short-lived (one heartbeat check) so
391+
# listener registration and logging level are stable for its lifetime.
392+
self._should_publish = listeners is not None and listeners.enabled_for_server_heartbeat
393+
self._should_log = _SDAM_LOGGER.isEnabledFor(logging.DEBUG)
388394

389395
def _emit_log(self, message: _SDAMStatusMessage, **extra: Any) -> None:
390396
_debug_log(
@@ -472,14 +478,17 @@ def __init__(
472478

473479
@property
474480
def _publish_server(self) -> bool:
481+
"""Computed per-call because listener registration can change while the topology is open."""
475482
return self._listeners is not None and self._listeners.enabled_for_server
476483

477484
@property
478485
def _publish_tp(self) -> bool:
486+
"""Computed per-call because listener registration can change while the topology is open."""
479487
return self._listeners is not None and self._listeners.enabled_for_topology
480488

481489
@property
482490
def _should_log(self) -> bool:
491+
"""Computed per-call because logging level can be reconfigured at runtime."""
483492
return _SDAM_LOGGER.isEnabledFor(logging.DEBUG)
484493

485494
def _enqueue(self, fn: Any, args: tuple[Any, ...]) -> None:
@@ -576,6 +585,7 @@ class has no publish methods.
576585
"_operation",
577586
"_operation_id",
578587
"_selector",
588+
"_should_log",
579589
"_topology_description",
580590
"_topology_id",
581591
)
@@ -593,10 +603,9 @@ def __init__(
593603
self._operation = operation
594604
self._operation_id = operation_id
595605
self._topology_description = topology_description
596-
597-
@property
598-
def _should_log(self) -> bool:
599-
return _SERVER_SELECTION_LOGGER.isEnabledFor(logging.DEBUG)
606+
# Cached at construction: this object is short-lived (one select_server call) so
607+
# logging level is stable for its lifetime.
608+
self._should_log = _SERVER_SELECTION_LOGGER.isEnabledFor(logging.DEBUG)
600609

601610
def _emit_log(self, message: _ServerSelectionStatusMessage, **extra: Any) -> None:
602611
_debug_log(

0 commit comments

Comments
 (0)