Skip to content

Commit 5848297

Browse files
committed
removed ABC from mixin, added try/catch block around executor shutdown
Signed-off-by: Sai Shree Pradhan <saishree.pradhan@databricks.com>
1 parent dad9ad5 commit 5848297

File tree

4 files changed

+39
-28
lines changed

4 files changed

+39
-28
lines changed

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ jobs:
6161
# run test suite
6262
#----------------------------------------------
6363
- name: Run tests
64-
run: poetry run python -m pytest tests/unit -v -s --log-cli-level=DEBUG
64+
run: poetry run python -m pytest tests/unit
6565
run-unit-tests-with-arrow:
6666
runs-on: ubuntu-latest
6767
strategy:
@@ -112,7 +112,7 @@ jobs:
112112
# run test suite
113113
#----------------------------------------------
114114
- name: Run tests
115-
run: poetry run python -m pytest tests/unit -v -s --log-cli-level=DEBUG
115+
run: poetry run python -m pytest tests/unit
116116
check-linting:
117117
runs-on: ubuntu-latest
118118
strategy:

src/databricks/sql/telemetry/telemetry_client.py

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,13 @@ class NoopTelemetryClient(BaseTelemetryClient):
123123
It is used when telemetry is disabled.
124124
"""
125125

126+
_instance = None
127+
128+
def __new__(cls):
129+
if cls._instance is None:
130+
cls._instance = super(NoopTelemetryClient, cls).__new__(cls)
131+
return cls._instance
132+
126133
def export_initial_telemetry_log(self, driver_connection_params, user_agent):
127134
pass
128135

@@ -133,10 +140,6 @@ def close(self):
133140
pass
134141

135142

136-
# A single instance of the no-op client that can be reused
137-
NOOP_TELEMETRY_CLIENT = NoopTelemetryClient()
138-
139-
140143
class TelemetryClient(BaseTelemetryClient):
141144
"""
142145
Telemetry client class that handles sending telemetry events in batches to the server.
@@ -369,11 +372,11 @@ def initialize_telemetry_client(
369372
executor=_executor,
370373
)
371374
else:
372-
_clients[session_id_hex] = NOOP_TELEMETRY_CLIENT
375+
_clients[session_id_hex] = NoopTelemetryClient()
373376
except Exception as e:
374377
logger.debug("Failed to initialize telemetry client: %s", e)
375378
# Fallback to NoopTelemetryClient to ensure connection doesn't fail
376-
_clients[session_id_hex] = NOOP_TELEMETRY_CLIENT
379+
_clients[session_id_hex] = NoopTelemetryClient()
377380

378381

379382
def get_telemetry_client(session_id_hex):
@@ -385,10 +388,10 @@ def get_telemetry_client(session_id_hex):
385388
logger.error(
386389
"Telemetry client not initialized for connection %s", session_id_hex
387390
)
388-
return NOOP_TELEMETRY_CLIENT
391+
return NoopTelemetryClient()
389392
except Exception as e:
390393
logger.debug("Failed to get telemetry client: %s", e)
391-
return NOOP_TELEMETRY_CLIENT
394+
return NoopTelemetryClient()
392395

393396

394397
def close_telemetry_client(session_id_hex):
@@ -401,10 +404,13 @@ def close_telemetry_client(session_id_hex):
401404
telemetry_client.close()
402405

403406
# Shutdown executor if no more clients
404-
if not _clients and _executor:
405-
logger.debug(
406-
"No more telemetry clients, shutting down thread pool executor"
407-
)
408-
_executor.shutdown(wait=True)
409-
_executor = None
410-
_initialized = False
407+
try:
408+
if not _clients and _executor:
409+
logger.debug(
410+
"No more telemetry clients, shutting down thread pool executor"
411+
)
412+
_executor.shutdown(wait=True)
413+
_executor = None
414+
_initialized = False
415+
except Exception as e:
416+
logger.debug("Failed to shutdown thread pool executor: %s", e)

src/databricks/sql/telemetry/utils.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
import json
22
from enum import Enum
33
from dataclasses import asdict, is_dataclass
4-
from abc import ABC
54

65

7-
class JsonSerializableMixin(ABC):
6+
class JsonSerializableMixin:
87
"""Mixin class to provide JSON serialization capabilities to dataclasses."""
98

109
def to_json(self) -> str:

tests/unit/test_telemetry.py

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
from databricks.sql.telemetry.telemetry_client import (
77
TelemetryClient,
8-
NOOP_TELEMETRY_CLIENT,
8+
NoopTelemetryClient,
99
initialize_telemetry_client,
1010
get_telemetry_client,
1111
close_telemetry_client,
@@ -30,8 +30,8 @@
3030

3131
@pytest.fixture
3232
def noop_telemetry_client():
33-
"""Fixture for NOOP_TELEMETRY_CLIENT."""
34-
return NOOP_TELEMETRY_CLIENT
33+
"""Fixture for NoopTelemetryClient."""
34+
return NoopTelemetryClient()
3535

3636

3737
@pytest.fixture
@@ -79,7 +79,13 @@ def telemetry_system_reset():
7979

8080

8181
class TestNoopTelemetryClient:
82-
"""Tests for the NOOP_TELEMETRY_CLIENT."""
82+
"""Tests for the NoopTelemetryClient."""
83+
84+
def test_singleton(self):
85+
"""Test that NoopTelemetryClient is a singleton."""
86+
client1 = NoopTelemetryClient()
87+
client2 = NoopTelemetryClient()
88+
assert client1 is client2
8389

8490
def test_export_initial_telemetry_log(self, noop_telemetry_client):
8591
"""Test that export_initial_telemetry_log does nothing."""
@@ -362,12 +368,12 @@ def test_initialize_telemetry_client_disabled(self, telemetry_system_reset):
362368
)
363369

364370
client = get_telemetry_client(session_id_hex)
365-
assert client is NOOP_TELEMETRY_CLIENT
371+
assert isinstance(client, NoopTelemetryClient)
366372

367373
def test_get_telemetry_client_nonexistent(self, telemetry_system_reset):
368374
"""Test getting a non-existent telemetry client."""
369375
client = get_telemetry_client("nonexistent-uuid")
370-
assert client is NOOP_TELEMETRY_CLIENT
376+
assert isinstance(client, NoopTelemetryClient)
371377

372378
def test_close_telemetry_client(self, telemetry_system_reset):
373379
"""Test closing a telemetry client."""
@@ -392,7 +398,7 @@ def test_close_telemetry_client(self, telemetry_system_reset):
392398
client.close.assert_called_once()
393399

394400
client = get_telemetry_client(session_id_hex)
395-
assert client is NOOP_TELEMETRY_CLIENT
401+
assert isinstance(client, NoopTelemetryClient)
396402

397403
def test_close_telemetry_client_noop(self, telemetry_system_reset):
398404
"""Test closing a no-op telemetry client."""
@@ -405,7 +411,7 @@ def test_close_telemetry_client_noop(self, telemetry_system_reset):
405411
)
406412

407413
client = get_telemetry_client(session_id_hex)
408-
assert client is NOOP_TELEMETRY_CLIENT
414+
assert isinstance(client, NoopTelemetryClient)
409415

410416
client.close = MagicMock()
411417

@@ -414,7 +420,7 @@ def test_close_telemetry_client_noop(self, telemetry_system_reset):
414420
client.close.assert_called_once()
415421

416422
client = get_telemetry_client(session_id_hex)
417-
assert client is NOOP_TELEMETRY_CLIENT
423+
assert isinstance(client, NoopTelemetryClient)
418424

419425
@patch("databricks.sql.telemetry.telemetry_client._handle_unhandled_exception")
420426
def test_global_exception_hook(self, mock_handle_exception, telemetry_system_reset):

0 commit comments

Comments
 (0)