fix(db-part-4): enforce consistent cross-resource lock ordering#5027
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
PR SummaryMedium Risk Overview Billing: Paid-org join now Knowledge / tables: Document tag updates write Advisory locks: Remaining 32-bit sites use Reviewed by Cursor Bugbot for commit b160c2d. Configure here. |
Greptile SummaryThis PR enforces consistent cross-resource lock ordering across several code paths to eliminate AB-BA deadlock potential, adds
Confidence Score: 4/5The production lock-ordering changes are logically sound and consistent across all affected paths; the main concern is in the updated test for invoices.ts whose assertions may not actually verify the ordering they claim to guard. The deadlock-prevention logic in every production file looks correct — the canonical userStats → organization, subscription → userStats, embedding → document, and rows_pos → definitions orderings are consistently established. The test regression guards for knowledge, table, and billing/organizations use reliable invocationCallOrder patterns. The invoices.test.ts guard, however, relies on strict equality between Drizzle column objects and plain strings, which is unlikely to hold; if those assertions silently mismatch, the PR's own regression net for the invoices path has a gap. The hashtext → hashtextextended key migration is also worth a note for deployments that overlap old and new instances. apps/sim/lib/billing/webhooks/invoices.test.ts — the new lock-order assertion logic should be verified; apps/sim/app/api/schedules/execute/route.ts — advisory lock key migration needs care in rolling-deploy scenarios. Important Files Changed
Sequence DiagramsequenceDiagram
participant A as applyPaidOrgJoinBillingTx
participant B as restoreUserProSubscription
participant C as resetUsageForSubscription
participant D as captureDepartedUsage
Note over A,D: Canonical lock order (fixed in this PR)
A->>A: SELECT subscription FOR UPDATE
A->>A: SELECT userStats FOR UPDATE
A->>A: UPDATE userStats (snapshot)
A->>A: UPDATE subscription (cancel)
B->>B: SELECT subscription FOR UPDATE
B->>B: SELECT userStats FOR UPDATE
B->>B: UPDATE userStats (restore)
C->>C: SELECT member (owner) FOR UPDATE
C->>C: SELECT userStats (owner) FOR UPDATE
C->>C: SELECT userStats (all members) FOR UPDATE
C->>C: SELECT organization FOR UPDATE
C->>C: UPDATE userStats (reset)
C->>C: UPDATE organization
D->>D: SELECT userStats FOR UPDATE
D->>D: UPDATE organization (implicit lock)
D->>D: UPDATE userStats
Reviews (1): Last reviewed commit: "fix(db-part-4): enforce consistent cross..." | Re-trigger Greptile |
Summary
knowledge: updateDocument locks embeddings before the document row, matching
the chunk-mutation paths (embedding → document)
tables: column-creating CSV imports take the rows_pos advisory before writing
user_table_definitions, matching the order plain inserts use
billing: lock userStats before organization across all paths (flip
captureDepartedUsage + resetUsageForSubscription to match the join, threshold,
and storage-transfer paths), and subscription before userStats on paid-org
join (matching restoreUserProSubscription)
harden the workspace env/byok/file-folder advisory locks with a 5s
lock_timeout, and switch hashtext → hashtextextended (64-bit) at the remaining
32-bit advisory sites to cut spurious collisions
Type of Change
Testing
Tested manually
Checklist