Skip to content

Commit d7c75d7

Browse files
committed
debug on TelemetryClientFactory lock
Signed-off-by: Sai Shree Pradhan <saishree.pradhan@databricks.com>
1 parent fc918d6 commit d7c75d7

File tree

2 files changed

+73
-2
lines changed

2 files changed

+73
-2
lines changed

.github/workflows/code-quality-checks.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ jobs:
112112
# run test suite
113113
#----------------------------------------------
114114
- name: Run tests
115-
run: poetry run python -m pytest tests/unit
115+
run: poetry run python -m pytest tests/unit -v -s
116116
check-linting:
117117
runs-on: ubuntu-latest
118118
strategy:

src/databricks/sql/telemetry/telemetry_client.py

Lines changed: 72 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,76 @@
3131
logger = logging.getLogger(__name__)
3232

3333

34+
class DebugLock:
35+
"""A wrapper around threading.Lock that provides detailed debugging for lock acquisition/release"""
36+
def __init__(self, name: str = "DebugLock"):
37+
self._lock = threading.Lock()
38+
self._name = name
39+
self._owner = None
40+
self._waiters = []
41+
self._debug_logger = logging.getLogger(f"{__name__}.{name}")
42+
# Ensure debug logging is visible
43+
if not self._debug_logger.handlers:
44+
handler = logging.StreamHandler()
45+
formatter = logging.Formatter(
46+
":lock: %(asctime)s [%(threadName)s-%(thread)d] LOCK-%(name)s: %(message)s"
47+
)
48+
handler.setFormatter(formatter)
49+
self._debug_logger.addHandler(handler)
50+
self._debug_logger.setLevel(logging.DEBUG)
51+
def acquire(self, blocking=True, timeout=-1):
52+
current = threading.current_thread()
53+
thread_info = f"{current.name}-{current.ident}"
54+
if self._owner:
55+
self._debug_logger.warning(
56+
f":rotating_light: WAITING: {thread_info} waiting for lock held by {self._owner}"
57+
)
58+
self._waiters.append(thread_info)
59+
else:
60+
self._debug_logger.debug(
61+
f":large_green_circle: TRYING: {thread_info} attempting to acquire lock"
62+
)
63+
# Try to acquire the lock
64+
acquired = self._lock.acquire(blocking, timeout)
65+
if acquired:
66+
self._owner = thread_info
67+
self._debug_logger.info(f":white_check_mark: ACQUIRED: {thread_info} got the lock")
68+
if self._waiters:
69+
self._debug_logger.info(
70+
f":clipboard: WAITERS: {len(self._waiters)} threads waiting: {self._waiters}"
71+
)
72+
else:
73+
self._debug_logger.error(
74+
f":x: FAILED: {thread_info} failed to acquire lock (timeout)"
75+
)
76+
if thread_info in self._waiters:
77+
self._waiters.remove(thread_info)
78+
return acquired
79+
def release(self):
80+
current = threading.current_thread()
81+
thread_info = f"{current.name}-{current.ident}"
82+
if self._owner != thread_info:
83+
self._debug_logger.error(
84+
f":rotating_light: ERROR: {thread_info} trying to release lock owned by {self._owner}"
85+
)
86+
else:
87+
self._debug_logger.info(f":unlock: RELEASED: {thread_info} released the lock")
88+
self._owner = None
89+
# Remove from waiters if present
90+
if thread_info in self._waiters:
91+
self._waiters.remove(thread_info)
92+
if self._waiters:
93+
self._debug_logger.info(
94+
f":loudspeaker: NEXT: {len(self._waiters)} threads still waiting: {self._waiters}"
95+
)
96+
self._lock.release()
97+
def __enter__(self):
98+
self.acquire()
99+
return self
100+
def __exit__(self, exc_type, exc_val, exc_tb):
101+
self.release()
102+
103+
34104
class TelemetryHelper:
35105
"""Helper class for getting telemetry related information."""
36106

@@ -355,7 +425,8 @@ class TelemetryClientFactory:
355425
] = {} # Map of session_id_hex -> BaseTelemetryClient
356426
_executor: Optional[ThreadPoolExecutor] = None
357427
_initialized: bool = False
358-
_lock = threading.Lock() # Thread safety for factory operations
428+
# _lock = threading.Lock() # Thread safety for factory operations
429+
_lock = DebugLock("TelemetryClientFactory") # Thread safety for factory operations with debugging
359430
_original_excepthook = None
360431
_excepthook_installed = False
361432

0 commit comments

Comments
 (0)