fix(arcade): implement optimistic locking in session manager

Add version-based optimistic locking to prevent race conditions when
multiple moves arrive rapidly. The database update now checks that the
version hasn't changed since the move was validated, preventing moves
from overwriting each other with stale state.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Thomas Hallock 2025-10-23 13:18:48 -05:00
parent 3d8da2348b
commit 71fd66d96a
1 changed files with 8 additions and 6 deletions

View File

@ -3,7 +3,7 @@
* Handles database operations and validation for arcade sessions
*/
import { eq } from 'drizzle-orm'
import { eq, and } from 'drizzle-orm'
import { db, schema } from '@/db'
import { buildPlayerOwnershipMap, type PlayerOwnershipMap } from './player-ownership'
import { getValidator, type GameName } from './validators'
@ -249,17 +249,19 @@ export async function applyGameMove(
version: session.version + 1,
})
.where(
eq(schema.arcadeSessions.roomId, session.roomId) // Use roomId (PRIMARY KEY)
and(
eq(schema.arcadeSessions.roomId, session.roomId), // Use roomId (PRIMARY KEY)
eq(schema.arcadeSessions.version, session.version) // Optimistic locking
)
)
// Version check for optimistic locking would go here
// SQLite doesn't support WHERE clauses in UPDATE with RETURNING easily
// We'll handle this by checking the version after
.returning()
if (!updatedSession) {
// Version conflict - another move was processed first
return {
success: false,
error: 'Failed to update session',
error: 'Version conflict - please retry',
versionConflict: true,
}
}