fix: serialize concurrent profile deletions with RLock#60
Open
Sidbad12 wants to merge 1 commit into
Open
Conversation
|
@Sidbad12 is attempting to deploy a commit to the Vasu-Devs' projects Team on Vercel. A member of the Team first needs to authorize it. |
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.
Summary
What changed:
Added a reentrant thread lock (
_profile_write_lock/threading.RLock) inbackend/data/graph/profile.pythat wraps the 5 functions performing read-modify-write operations on the SQLite profile state. Also added a new concurrency regression test intests/test_concurrent_profile_delete.py.Why:
When a user rapidly deletes multiple profile items (e.g., skills or experience), concurrent FastAPI thread pool workers race on the SQLite snapshot read-modify-write cycle. The last writer overwrites earlier writers, causing the deleted items to lose their tombstones, resurface in the UI, and remain permanently in the Kùzu graph and vector databases. Serializing these writes resolves the race condition natively on the backend.
Type of Change
Testing
Commands run:
npm run typechecknpm testnpm run buildbackend/.venv/Scripts/python.exe -m pytest backend/tests(247 passing)cd src-tauri && cargo check.venv\Scripts\pytest tests\test_concurrent_profile_delete.py -v(concurrency test passes)Privacy And Safety
Licensing
CLA.mdand understand this contribution may be distributed under AGPL-3.0-only and separate commercial licenses.Notes For Reviewers
delete_skillinternally calls_remember_profile_deletionandsave_profile_snapshot. Using a standardLockwould cause the thread to deadlock itself.RLockelegantly handles this re-entry.deletingItemsSet), so it won't fire duplicate deletes for the same item. The race condition only happens when different items are deleted rapidly, which is a purely backend concern.