Skip to content

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. #21

Description

@Bryan-Roe

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)

Metadata

Metadata

Assignees

Labels

No labels
No labels

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions