Skip to content

fix: avoid memory authorization and activity publication deadlocks - #1397

Merged
tannerlinsley merged 1 commit into
mainfrom
taren/memory-activity-locks
Oct 17, 2026
Merged

tannerlinsley merged 1 commit into
mainfrom
taren/memory-activity-locks

Conversation

@tannerlinsley

@tannerlinsley tannerlinsley commented Oct 17, 2026 •

Copy link
Copy Markdown
Member

Changing memory recall preferences can deadlock with background activity publication. Keep the authorization rows locked while allowing publication's foreign-key checks to proceed.

AI review notes: The PostgreSQL service log identifies Memories.authorize and the activity outbox insert as the two deadlocking transactions. Authorization now uses FOR NO KEY UPDATE for the bot, conversation and membership rows. This remains incompatible with updates and deletion of those authorization rows, while permitting the foreign-key KEY SHARE locks used by publication.

The new regression calls the actual memory service while another transaction holds the conversation's foreign-key lock. It fails against the old implementation and passes with this change. A separate two-connection experiment reproduces 40P01 with the old lock mode and completes with the new one; checks also confirm bot archival and membership deletion remain blocked while authorization locks are held.

Validation: all 279 PostgreSQL runtime tests passed across 35 files. The final memory suite passed all 10 tests after correcting its transaction query typing. pnpm test passed: TypeScript/lint, 577 unit tests with 4 skipped, 2,270 chat tests, and 20 desktop tests with 1 skipped. These are isolated local database checks, not production concurrency measurements.

Fixes #1396.

Summary by CodeRabbit

  • Bug Fixes
    • Reduced unnecessary database lock contention when enabling memory preferences, helping preference updates complete without waiting on unrelated operations.

@changeset-bot

changeset-bot Bot commented Oct 17, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: ba51e52

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@coderabbitai

coderabbitai Bot commented Oct 17, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: bca02e35-3452-4f23-a792-1e277e65dbf6
📥 Commits

Reviewing files that changed from the base of the PR and between 053dc31 and ba51e52.

📒 Files selected for processing: 2
  • harness-tests/pending-runtime/memory-runtime.test.ts
  • src/chat/server/memory.ts

Included review availability: This review used your included allowance. Your plan provides up to 4 included reviews per hour; 3 remain after this review.

📝 Walkthrough

Transactional memory authorization now uses no key update row locks. A runtime regression test checks that enabling memory preferences does not wait on a monitored lock and verifies the resulting preference revision.

Changes: Memory preference locking

Layer / File(s) Summary
Transactional authorization locks and regression test
src/chat/server/memory.ts, harness-tests/pending-runtime/memory-runtime.test.ts
Memories.authorize uses no key update locks for selected rows in transactions. The regression test holds a conversation key-share lock, monitors for a wait, and verifies that enabling preferences completes at revision 1.

Priority: ➖ Normal

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Bug fix

Merge Risk: ⚪ Minimal · up to ba51e

The authorization lock change has no identified merge-blocking issue; the regression test covers the reported old-mode wait.

Pre-merge checks: Passed 5
Check name Status Explanation
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check Passed The title accurately summarizes the primary change: preventing deadlocks between memory authorization and activity publication.
Linked Issues check Passed Issue #1396 requires identifying the deadlock between memory authorization and activity publication, correcting the lock ordering without weakening authorization, and avoiding blanket retries. The PR …
Out of Scope Changes check Passed The PR changes one authorization lock mode and adds one focused regression test. Both changes directly support issue #1396 by preventing the activity publication foreign-key lock conflict while retain…
Docstring Coverage Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 2…
Full details: Linked Issues check

Explanation

Issue #1396 requires identifying the deadlock between memory authorization and activity publication, correcting the lock ordering without weakening authorization, and avoiding blanket retries. The PR changes transactional authorization locks in Memories.authorize from FOR UPDATE to FOR NO KEY UPDATE for the bot, conversation, and membership rows. The regression test holds a conversation FOR KEY SHARE lock and calls the actual setPreferences service. The reported validation also reproduces the old 40P01 failure and verifies archival and membership deletion remain blocked. No retry or Sentry filtering change is present, so the separate scope in #1327 remains intact.

Full details: Out of Scope Changes check

Explanation

The PR changes one authorization lock mode and adds one focused regression test. Both changes directly support issue #1396 by preventing the activity publication foreign-key lock conflict while retaining authorization locks. No unrelated implementation or test changes are shown.

Full details: Docstring Coverage

Explanation

No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 2 files.

✨ Finishing Touches
📝 Generate docstrings
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
tanstack-com ba51e52 Commit Preview URL

Branch Preview URL
Oct 17 2026, 02:01 PM

@tannerlinsley
tannerlinsley merged commit c591f46 into main Oct 17, 2026
8 checks passed
@tannerlinsley
tannerlinsley deleted the taren/memory-activity-locks branch October 17, 2026 14:08
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.

Intermittent PostgreSQL deadlock while changing memory recall preferences

1 participant