Consolidating to asyncio.Lock over threading.Lock#442
Conversation
There was a problem hiding this comment.
Pull request overview
This PR updates the in-memory storage implementations to use asyncio.Lock/async with instead of threading.Lock/with, aligning concurrency control with the project’s async execution model and avoiding blocking the event loop.
Changes:
- Switched
MemoryStorageto useasyncio.Lockandasync withfor read/write/delete critical sections. - Switched
TranscriptMemoryStoreto useasyncio.Lockandasync withfor transcript mutation and queries.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| libraries/microsoft-agents-hosting-core/microsoft_agents/hosting/core/storage/memory_storage.py | Replaces sync locking with asyncio.Lock and async context management around in-memory state access. |
| libraries/microsoft-agents-hosting-core/microsoft_agents/hosting/core/storage/transcript_memory_store.py | Replaces sync locking with asyncio.Lock and async context management around transcript operations. |
Comments suppressed due to low confidence (1)
libraries/microsoft-agents-hosting-core/microsoft_agents/hosting/core/storage/memory_storage.py:33
- Inside MemoryStorage.read(), target_cls is validated as non-None before the lock, so the later
if not target_cls:branch is unreachable. This dead branch also forcesresultto be typed as dict[str, StoreItem] even though the method returns dict[str, StoreItemT]. Simplify the branch and align the type annotation.
async with self._lock:
for key in keys:
if key == "":
raise ValueError("MemoryStorage.read(): key cannot be empty")
if key in self._memory:
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
Comments suppressed due to low confidence (3)
libraries/microsoft-agents-hosting-core/microsoft_agents/hosting/core/storage/memory_storage.py:33
- In an async context, it’s better to validate keys before awaiting on the lock. As written, an invalid key can still acquire the lock first, unnecessarily blocking other coroutines.
async with self._lock:
for key in keys:
if key == "":
raise ValueError("MemoryStorage.read(): key cannot be empty")
if key in self._memory:
libraries/microsoft-agents-hosting-core/microsoft_agents/hosting/core/storage/memory_storage.py:55
- In an async context, validate inputs before awaiting on the lock. This avoids acquiring the lock (and potentially blocking other tasks) when the request is invalid.
async with self._lock:
for key in changes:
if key == "":
raise ValueError("MemoryStorage.write(): key cannot be empty")
self._memory[key] = changes[key].store_item_to_json()
libraries/microsoft-agents-hosting-core/microsoft_agents/hosting/core/storage/memory_storage.py:65
- In an async context, validate inputs before awaiting on the lock. This prevents invalid input from taking the lock and briefly blocking other coroutines.
async with self._lock:
for key in keys:
if key == "":
raise ValueError("MemoryStorage.delete(): key cannot be empty")
if key in self._memory:
| # Licensed under the MIT License. | ||
|
|
||
| from threading import Lock | ||
| from asyncio import Lock |
| This class is async-safe and stores all activities in a list. It supports logging activities, | ||
| retrieving activities for a specific channel and conversation, and filtering by timestamp. |
| An in-memory implementation of the TranscriptLogger for storing and retrieving activities. | ||
|
|
||
| This class is thread-safe and stores all activities in a list. It supports logging activities, | ||
| This class is async-safe and stores all activities in a list. It supports logging activities, |
This pull request updates the in-memory storage and transcript store implementations to use
asyncio.Lockandasync withfor concurrency control instead of the standard threadingLock. This change ensures that locking is compatible with asynchronous code, preventing potential deadlocks or blocking in async environments.Concurrency model update:
Replaced
threading.Lockwithasyncio.Lockin bothmemory_storage.pyandtranscript_memory_store.pyto ensure proper synchronization in async contexts. [1] [2]Updated all critical sections in
MemoryStoragemethods (read,write,delete) to useasync with self._lock:instead ofwith self._lock:. [1] [2] [3]Updated all critical sections in
TranscriptMemoryStoremethods (log_activity,get_transcript_activities,delete_transcript,list_transcripts) to useasync with self.lock:instead ofwith self.lock:. [1] [2] [3] [4]