Skip to content

Commit cfd0653

Browse files
committed
[change] Bound ConnectionCache to AtlanClient, moved class var to TLS
1 parent 278854e commit cfd0653

File tree

2 files changed

+41
-24
lines changed

2 files changed

+41
-24
lines changed

pyatlan/cache/connection_cache.py

Lines changed: 33 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,24 @@
11
# SPDX-License-Identifier: Apache-2.0
2-
# Copyright 2024 Atlan Pte. Ltd.
2+
# Copyright 2025 Atlan Pte. Ltd.
33
from __future__ import annotations
44

55
import logging
66
import threading
7-
from typing import Dict, Optional, Union
7+
from threading import local
8+
from typing import TYPE_CHECKING, Optional, Union
89

910
from pyatlan.cache.abstract_asset_cache import AbstractAssetCache, AbstractAssetName
10-
from pyatlan.client.atlan import AtlanClient
1111
from pyatlan.model.assets import Asset, Connection
1212
from pyatlan.model.enums import AtlanConnectorType
1313
from pyatlan.model.fluent_search import FluentSearch
1414
from pyatlan.model.search import Term
1515

16+
if TYPE_CHECKING:
17+
from pyatlan.client.atlan import AtlanClient
1618
LOGGER = logging.getLogger(__name__)
1719

1820
lock = threading.Lock()
21+
connection_cache_tls = local() # Thread-local storage (TLS)
1922

2023

2124
class ConnectionCache(AbstractAssetCache):
@@ -37,21 +40,26 @@ class ConnectionCache(AbstractAssetCache):
3740
Connection.CONNECTOR_NAME,
3841
]
3942
SEARCH_ATTRIBUTES = [field.atlan_field_name for field in _SEARCH_FIELDS]
40-
caches: Dict[int, ConnectionCache] = dict()
4143

4244
def __init__(self, client: AtlanClient):
4345
super().__init__(client)
4446

4547
@classmethod
46-
def get_cache(cls) -> ConnectionCache:
48+
def get_cache(cls, client: Optional[AtlanClient] = None) -> ConnectionCache:
4749
from pyatlan.client.atlan import AtlanClient
4850

4951
with lock:
50-
default_client = AtlanClient.get_default_client()
51-
cache_key = default_client.cache_key
52-
if cache_key not in cls.caches:
53-
cls.caches[cache_key] = ConnectionCache(client=default_client)
54-
return cls.caches[cache_key]
52+
client = client or AtlanClient.get_default_client()
53+
cache_key = client.cache_key
54+
55+
if not hasattr(connection_cache_tls, "caches"):
56+
connection_cache_tls.caches = {}
57+
58+
if cache_key not in connection_cache_tls.caches:
59+
cache_instance = ConnectionCache(client=client)
60+
connection_cache_tls.caches[cache_key] = cache_instance
61+
62+
return connection_cache_tls.caches[cache_key]
5563

5664
@classmethod
5765
def get_by_guid(cls, guid: str, allow_refresh: bool = True) -> Connection:
@@ -139,21 +147,22 @@ def lookup_by_qualified_name(self, connection_qn: str) -> None:
139147
def lookup_by_name(self, name: ConnectionName) -> None:
140148
if not isinstance(name, ConnectionName):
141149
return
142-
results = self.client.asset.find_connections_by_name(
143-
name=name.name,
144-
connector_type=name.type,
145-
attributes=self.SEARCH_ATTRIBUTES,
146-
)
147-
if not results:
148-
return
149-
if len(results) > 1:
150-
LOGGER.warning(
151-
(
152-
"Found multiple connections of the same type with the same name, caching only the first: %s"
153-
),
154-
name,
150+
with self.lock:
151+
results = self.client.asset.find_connections_by_name(
152+
name=name.name,
153+
connector_type=name.type,
154+
attributes=self.SEARCH_ATTRIBUTES,
155155
)
156-
self.cache(results[0])
156+
if not results:
157+
return
158+
if len(results) > 1:
159+
LOGGER.warning(
160+
(
161+
"Found multiple connections of the same type with the same name, caching only the first: %s"
162+
),
163+
name,
164+
)
165+
self.cache(results[0])
157166

158167
def get_name(self, asset: Asset):
159168
if not isinstance(asset, Connection):

pyatlan/client/atlan.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
from urllib3.util.retry import Retry
4343

4444
from pyatlan.cache.atlan_tag_cache import AtlanTagCache
45+
from pyatlan.cache.connection_cache import ConnectionCache
4546
from pyatlan.cache.custom_metadata_cache import CustomMetadataCache
4647
from pyatlan.cache.enum_cache import EnumCache
4748
from pyatlan.cache.group_cache import GroupCache
@@ -182,6 +183,7 @@ class AtlanClient(BaseSettings):
182183
_role_cache: Optional[RoleCache] = PrivateAttr(default=None)
183184
_user_cache: Optional[UserCache] = PrivateAttr(default=None)
184185
_custom_metadata_cache: Optional[CustomMetadataCache] = PrivateAttr(default=None)
186+
_connection_cache: Optional[ConnectionCache] = PrivateAttr(default=None)
185187

186188
class Config:
187189
env_prefix = "atlan_"
@@ -367,6 +369,12 @@ def custom_metadata_cache(self) -> CustomMetadataCache:
367369
self._custom_metadata_cache = CustomMetadataCache.get_cache(client=self)
368370
return self._custom_metadata_cache
369371

372+
@property
373+
def connection_cache(self) -> ConnectionCache:
374+
if self._connection_cache is None:
375+
self._connection_cache = ConnectionCache.get_cache(client=self)
376+
return self._connection_cache
377+
370378
def update_headers(self, header: Dict[str, str]):
371379
self._session.headers.update(header)
372380

0 commit comments

Comments
 (0)