Fix deadlock in lazy init: _ensure_initialized calling login via request()
login() called client.request() which called _ensure_initialized() which tried to re-acquire _init_lock — deadlocking forever. Fix: set _initializing=True while inside the init critical section so request() skips the _ensure_initialized() guard when called from within init (safe because query_api_info() already populated the API cache). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -101,6 +101,7 @@ class DsmClient:
|
||||
self._reauth_lock = asyncio.Lock()
|
||||
self._init_lock = asyncio.Lock()
|
||||
self._initialized = False
|
||||
self._initializing = False # True while inside _ensure_initialized
|
||||
logger.debug(
|
||||
"DsmClient: base_url=%s verify_ssl=%s timeout=%d",
|
||||
self._base_url,
|
||||
@@ -131,6 +132,8 @@ class DsmClient:
|
||||
async with self._init_lock:
|
||||
if self._initialized: # re-check inside lock
|
||||
return
|
||||
self._initializing = True
|
||||
try:
|
||||
sys.stderr.write(f"[dsm] Connecting to {self._base_url}...\n")
|
||||
sys.stderr.flush()
|
||||
logger.debug("Lazy init: querying API info from %s", self._base_url)
|
||||
@@ -146,6 +149,8 @@ class DsmClient:
|
||||
sys.stderr.flush()
|
||||
self._initialized = True
|
||||
logger.debug("Lazy init complete")
|
||||
finally:
|
||||
self._initializing = False
|
||||
|
||||
async def __aenter__(self) -> DsmClient:
|
||||
logging.getLogger("httpx").setLevel(logging.WARNING)
|
||||
@@ -235,6 +240,9 @@ class DsmClient:
|
||||
"""
|
||||
sys.stderr.write(f"[dsm] request: {api}/{method}\n")
|
||||
sys.stderr.flush()
|
||||
# Skip init guard if we are already inside _ensure_initialized (e.g. login call).
|
||||
# The API cache is populated before login, so the cache is ready at this point.
|
||||
if not self._initializing:
|
||||
await self._ensure_initialized()
|
||||
http = self._get_http()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user