fix(memory): serialize concurrent add() calls with asyncio.Lock#1428
Open
octo-patch wants to merge 1 commit intoagentscope-ai:mainfrom
Open
fix(memory): serialize concurrent add() calls with asyncio.Lock#1428octo-patch wants to merge 1 commit intoagentscope-ai:mainfrom
octo-patch wants to merge 1 commit intoagentscope-ai:mainfrom
Conversation
…agentscope-ai#1381) When ReActAgent runs with parallel_tool_calls=True, multiple _acting coroutines can invoke AsyncSQLAlchemyMemory.add() concurrently. Without serialization, two coroutines can both pass the skip_duplicated check (both observe the same DB state before either has committed), then both attempt to insert the same message, causing an IntegrityError on the primary key. Add an asyncio.Lock around the read-check-then-write section of add() so that concurrent calls are serialized per memory instance. The lock wraps the duplicate check, index assignment, message insert, mark insert, and commit as one atomic critical section.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #1381
Problem
When
ReActAgentruns withparallel_tool_calls=True, multiple_actingcoroutines invokeAsyncSQLAlchemyMemory.add()concurrently. Without serialization:The same race condition affects
_get_next_index(), where two concurrent calls can read the same max index, leading both to attempt inserts with the sameindexvalue.Solution
Add an
asyncio.LocktoAsyncSQLAlchemyMemoryand wrap the entire check-then-write section ofadd()(duplicate check → index read → message insert → mark insert → commit) inasync with self._lock:. This serializes concurrentadd()calls per memory instance, eliminating the TOCTOU race condition.Testing
asyncio.Lockprevents concurrent coroutines from interleaving their read-check-insert-commit sequences.AsyncSQLAlchemyMemoryinstances are not affected.