Skip to content

Add per-user request locks to prevent race conditions#54

Merged
xumaple merged 5 commits intomainfrom
xumaple/copilot/locks
Apr 11, 2026
Merged

Add per-user request locks to prevent race conditions#54
xumaple merged 5 commits intomainfrom
xumaple/copilot/locks

Conversation

@xumaple
Copy link
Copy Markdown
Owner

@xumaple xumaple commented Apr 4, 2026

Summary

  • Adds DashMap-based per-user locking for all mutating API handlers (create user, update user, add/change password, delete user)
  • Each user's ObjectId maps to an Arc<tokio::sync::Mutex<()>> — concurrent writes to the same user are serialized, different users are unblocked
  • User creation uses the same pattern (no separate global lock needed — the DashMap entry API handles atomic insert-or-get)
  • Read-only handlers are unaffected

Closes #6

Test plan

  • Unit tests pass (32 tests)
  • Integration tests pass (20 tests, including new concurrency test)
  • Clippy clean
  • New test: test_concurrent_password_adds_are_serialized — fires 10 concurrent password additions, verifies no data loss

🤖 Generated with Claude Code

@vercel
Copy link
Copy Markdown

vercel Bot commented Apr 4, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
website Ready Ready Preview, Comment Apr 11, 2026 0:25am

xumaple and others added 4 commits April 10, 2026 20:05
Use DashMap<ObjectId, Arc<tokio::sync::Mutex<()>>> to serialize all
mutating requests per user. Covers create_user, update_user,
add_stored_password, change_stored_password, and delete_user.
Read-only handlers are unaffected. Closes #6.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
State provides compile-time guarantees that the state was provided,
unlike Extension which panics at runtime if missing.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Locking protects DB operations, so it belongs in the db layer.
Handlers no longer need to know about locks, and the duplicated
user2oid calls are eliminated.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Grab the per-user lock after authenticate_user returns, using the
en_user it already computed. Removes the duplicate user2oid calls
without needing a separate function.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
After acquiring the per-user lock in change_master_password and
add_stored_password, re-read the user from DB and verify the master
key hasn't changed since authentication. Prevents concurrent requests
from proceeding with stale credentials after another request changed
the master password.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@xumaple xumaple merged commit 1d97c81 into main Apr 11, 2026
5 checks passed
@xumaple xumaple deleted the xumaple/copilot/locks branch April 11, 2026 03:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

PM: Add locks to prevent race conditions

1 participant