hermes - 💡(How to fix) Fix concurrency: _openrouter_prewarm_done.is_set()+.set() non-atomic — can spawn duplicate prewarm threads

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…

Fix Action

Fix

Replace the Event with a threading.Lock used as a one-shot gate via acquire(blocking=False): only the first caller gets the lock (never released), all subsequent callers see the lock held and skip thread spawn.

Code Example

if ... and not _openrouter_prewarm_done.is_set():
    _openrouter_prewarm_done.set()
    threading.Thread(target=fetch_model_metadata, ...).start()
RAW_BUFFERClick to expand / collapse

Bug

The prewarm guard in run_agent.py uses a non-atomic check-then-act on threading.Event:

if ... and not _openrouter_prewarm_done.is_set():
    _openrouter_prewarm_done.set()
    threading.Thread(target=fetch_model_metadata, ...).start()

is_set() + set() are two separate operations — not atomic. Two concurrent AIAgent.__init__ calls (every gateway request creates one) can both see is_set() == False, both call .set(), and both start a fetch_model_metadata thread. The comment explicitly says the guard exists to prevent per-message thread leaks.

While the Event limits the leak to a small burst at startup rather than per-message, it violates the stated invariant.

Fix

Replace the Event with a threading.Lock used as a one-shot gate via acquire(blocking=False): only the first caller gets the lock (never released), all subsequent callers see the lock held and skip thread spawn.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

hermes - 💡(How to fix) Fix concurrency: _openrouter_prewarm_done.is_set()+.set() non-atomic — can spawn duplicate prewarm threads