What
All singletons use the pattern:
global _client
if _client is None:
_client = CohereClient()
return _client
In a concurrent async context, multiple coroutines can read _client is None as True simultaneously and each create a new instance.
Why
While only one "wins" the assignment, the others may have partially initialized state.
Scope
- Use
asyncio.Lock or module-level eager initialization
Acceptance Criteria
Technical Context
- Files:
src/services/cohere_client.py, lines 148-151
src/services/embedding.py, lines 62-64
src/services/generation.py, lines 130-132
src/services/quiz_generator.py, lines 125-127
src/services/feedback_engine.py, lines 130-132
src/knowledge/vectorstore.py, lines 170-174
What
All singletons use the pattern:
In a concurrent async context, multiple coroutines can read
_client is NoneasTruesimultaneously and each create a new instance.Why
While only one "wins" the assignment, the others may have partially initialized state.
Scope
asyncio.Lockor module-level eager initializationAcceptance Criteria
Technical Context
src/services/cohere_client.py, lines 148-151src/services/embedding.py, lines 62-64src/services/generation.py, lines 130-132src/services/quiz_generator.py, lines 125-127src/services/feedback_engine.py, lines 130-132src/knowledge/vectorstore.py, lines 170-174