fix: add size cap to assistant thread metadata cache
Prevents unbounded memory growth in _assistant_threads dict. Evicts oldest entries when exceeding _ASSISTANT_THREADS_MAX (5000), matching the pattern used by _mentioned_threads and _seen_messages.
This commit is contained in:
@@ -100,6 +100,7 @@ class SlackAdapter(BasePlatformAdapter):
|
|||||||
# events, and they carry the user/thread identity needed for stable
|
# events, and they carry the user/thread identity needed for stable
|
||||||
# session + memory scoping.
|
# session + memory scoping.
|
||||||
self._assistant_threads: Dict[Tuple[str, str], Dict[str, str]] = {}
|
self._assistant_threads: Dict[Tuple[str, str], Dict[str, str]] = {}
|
||||||
|
self._ASSISTANT_THREADS_MAX = 5000
|
||||||
|
|
||||||
async def connect(self) -> bool:
|
async def connect(self) -> bool:
|
||||||
"""Connect to Slack via Socket Mode."""
|
"""Connect to Slack via Socket Mode."""
|
||||||
@@ -826,6 +827,12 @@ class SlackAdapter(BasePlatformAdapter):
|
|||||||
merged.update({k: v for k, v in metadata.items() if v})
|
merged.update({k: v for k, v in metadata.items() if v})
|
||||||
self._assistant_threads[key] = merged
|
self._assistant_threads[key] = merged
|
||||||
|
|
||||||
|
# Evict oldest entries when the cache exceeds the limit
|
||||||
|
if len(self._assistant_threads) > self._ASSISTANT_THREADS_MAX:
|
||||||
|
excess = len(self._assistant_threads) - self._ASSISTANT_THREADS_MAX // 2
|
||||||
|
for old_key in list(self._assistant_threads)[:excess]:
|
||||||
|
del self._assistant_threads[old_key]
|
||||||
|
|
||||||
team_id = merged.get("team_id", "")
|
team_id = merged.get("team_id", "")
|
||||||
if team_id and channel_id:
|
if team_id and channel_id:
|
||||||
self._channel_team[channel_id] = team_id
|
self._channel_team[channel_id] = team_id
|
||||||
|
|||||||
@@ -927,6 +927,28 @@ class TestAssistantThreadLifecycle:
|
|||||||
assert msg_event.source.thread_id == "171.000"
|
assert msg_event.source.thread_id == "171.000"
|
||||||
assert msg_event.source.user_name == "Tyler"
|
assert msg_event.source.user_name == "Tyler"
|
||||||
|
|
||||||
|
def test_assistant_threads_cache_eviction(self, assistant_adapter):
|
||||||
|
"""Cache should evict oldest entries when exceeding the size limit."""
|
||||||
|
assistant_adapter._ASSISTANT_THREADS_MAX = 10
|
||||||
|
# Fill to the limit
|
||||||
|
for i in range(10):
|
||||||
|
assistant_adapter._cache_assistant_thread_metadata({
|
||||||
|
"channel_id": f"D{i}",
|
||||||
|
"thread_ts": f"{i}.000",
|
||||||
|
"user_id": f"U{i}",
|
||||||
|
})
|
||||||
|
assert len(assistant_adapter._assistant_threads) == 10
|
||||||
|
|
||||||
|
# Adding one more should trigger eviction (down to max // 2 = 5)
|
||||||
|
assistant_adapter._cache_assistant_thread_metadata({
|
||||||
|
"channel_id": "D999",
|
||||||
|
"thread_ts": "999.000",
|
||||||
|
"user_id": "U999",
|
||||||
|
})
|
||||||
|
assert len(assistant_adapter._assistant_threads) <= 10
|
||||||
|
# The newest entry must survive eviction
|
||||||
|
assert ("D999", "999.000") in assistant_adapter._assistant_threads
|
||||||
|
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
# TestUserNameResolution
|
# TestUserNameResolution
|
||||||
|
|||||||
Reference in New Issue
Block a user