The global _lmstudio_cache dictionary is not thread-safe. In Azure Functions, multiple concurrent requests can call _check_lmstudio_available() simultaneously, potentially causing race conditions when reading and writing cache entries.
Consider using threading.Lock or threading.RLock to protect cache access:
import threading
_lmstudio_cache: Dict[str, Any] = {"available": None, "checked_at": 0.0, "url": None}
_lmstudio_cache_lock = threading.RLock()
_LMSTUDIO_CACHE_TTL = 30
def _check_lmstudio_available(url: str) -> bool:
with _lmstudio_cache_lock:
now = time.time()
if (
_lmstudio_cache["available"] is not None
and _lmstudio_cache["url"] == url
and (now - _lmstudio_cache["checked_at"]) < _LMSTUDIO_CACHE_TTL
):
return _lmstudio_cache["available"]
# Perform check outside lock to avoid blocking other threads during HTTP request
try:
import urllib.request
req = urllib.request.Request(...)
urllib.request.urlopen(req, timeout=1)
available = True
except Exception:
available = False
with _lmstudio_cache_lock:
_lmstudio_cache["available"] = available
_lmstudio_cache["checked_at"] = time.time()
_lmstudio_cache["url"] = url
return available
Originally posted by @Copilot in #17 (comment)
The global
_lmstudio_cachedictionary is not thread-safe. In Azure Functions, multiple concurrent requests can call_check_lmstudio_available()simultaneously, potentially causing race conditions when reading and writing cache entries.Consider using
threading.Lockorthreading.RLockto protect cache access:Originally posted by @Copilot in #17 (comment)