P3-03: Double-checked locking on plugin _HTTP_CLIENT — race during concurrent init #21

Closed
opened 2026-06-16 13:57:02 +00:00 by Artur · 0 comments
Owner

Severity: P3 (Low)
File: ~/.hermes/plugins/decider/__init__.py lines 85-89

Problem

def _get_client(timeout):
    global _HTTP_CLIENT
    if _HTTP_CLIENT is None:  # race: two threads pass this check
        import httpx
        _HTTP_CLIENT = httpx.Client(timeout=timeout)
    return _HTTP_CLIENT

Two threads calling _call_decider simultaneously may both see _HTTP_CLIENT is None and create separate clients. Benign (just wasted connections) but a classic anti-pattern.

Fix

Use a module-level lock or initialize eagerly at module load time:

import httpx
_HTTP_CLIENT = httpx.Client(timeout=_DEFAULT_TIMEOUT)

def _get_client(timeout):
    return _HTTP_CLIENT
**Severity**: P3 (Low) **File**: `~/.hermes/plugins/decider/__init__.py` lines 85-89 ## Problem ```python def _get_client(timeout): global _HTTP_CLIENT if _HTTP_CLIENT is None: # race: two threads pass this check import httpx _HTTP_CLIENT = httpx.Client(timeout=timeout) return _HTTP_CLIENT ``` Two threads calling `_call_decider` simultaneously may both see `_HTTP_CLIENT is None` and create separate clients. Benign (just wasted connections) but a classic anti-pattern. ## Fix Use a module-level lock or initialize eagerly at module load time: ```python import httpx _HTTP_CLIENT = httpx.Client(timeout=_DEFAULT_TIMEOUT) def _get_client(timeout): return _HTTP_CLIENT ```
Artur closed this issue 2026-06-16 14:24:07 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
glow-all/decider#21
No description provided.