Skip to content

fix(libsql): serialize Factory writes on shared clients - #20278

Merged
wardpeet merged 1 commit into
mainfrom
fix/factory-libsql-write-contention
Jul 28, 2026
Merged

wardpeet merged 1 commit into
mainfrom
fix/factory-libsql-write-contention

Conversation

@wardpeet

@wardpeet wardpeet commented Jul 28, 2026 •

Copy link
Copy Markdown
Contributor

Factory storage shares a LibSQL client with the wrapped Mastra store, but its transactions and autocommit writes previously used a separate lock domain. Concurrent dispatcher claims could therefore collide with an open write transaction and report SQLITE_BUSY, while unrelated writes could also be swept into its commit or rollback.

Before, Factory writes used a private mutex only for updateAtomic(). After this change, complete Factory write operations, transactions, and schema updates use the existing per-client write queue. Transaction-scoped operations bypass recursive acquisition while the outer transaction owns the queue.

Added file-backed regression coverage for concurrent Factory transactions, Factory writes racing a rollback, and wrapped Mastra-domain writes sharing the client. Verified with the full @mastra/libsql suite (905 passed, 19 skipped), its TypeScript check, build, lint, and git diff --check.

ELI5

This PR makes shared LibSQL writes take turns instead of happening at the same time. This prevents transactions and other writes from interfering with each other and causing database lock errors.

What changed

  • Added a shared, per-client write queue for:
    • Factory transactions
    • Autocommit writes
    • Schema updates
  • Prevented nested queue acquisition for operations already running inside a transaction.
  • Preserved correct rollback behavior when Factory and Mastra-domain writes share a client.
  • Added file-backed regression tests for concurrent transactions, rollback races, and shared-client writes.
  • Added a patch changeset for @mastra/libsql.

Validation

  • @mastra/libsql suite: 905 passed, 19 skipped
  • TypeScript checks, build, lint, and git diff --check passed

Route Factory transactions and autocommit operations through the existing per-client write queue. This prevents concurrent dispatcher claims and other shared-client writes from colliding with open LibSQL transactions or being rolled back with unrelated work.

Add file-backed regression coverage for concurrent Factory transactions and writes racing a rollback.

Co-Authored-By: Mastra Code (openai/gpt-5.6-sol) <noreply@mastra.ai>
@changeset-bot

changeset-bot Bot commented Jul 28, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: cd6f096

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 6 packages
Name Type
@mastra/libsql Patch
@mastra/code-sdk Patch
mastracode Patch
@mastra/factory Patch
@mastra/opencode Patch
@mastra/longmemeval Patch

Not sure what this means? Click here to learn what changesets are.

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

@vercel

vercel Bot commented Jul 28, 2026 •

Copy link
Copy Markdown

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

Project Deployment Actions Updated (UTC)
mastra-docs-1.x Ready Ready Preview, Comment Jul 28, 2026 1:08am
mastra-playground-ui Ready Ready Preview, Comment Jul 28, 2026 1:08am
1 Skipped Deployment
Project Deployment Actions Updated (UTC)
mastra-studio-preview Ignored Ignored Jul 28, 2026 1:08am

Request Review

@dane-ai-mastra dane-ai-mastra Bot added is-contributor PR author is a member of the repository organization complexity: low Low-complexity PR labels Jul 28, 2026
@dane-ai-mastra

Copy link
Copy Markdown
Contributor

PR triage

Linked issue check skipped for core contributor @wardpeet.


PR complexity score

Factor Value Score impact
Files changed 3 +6
Lines changed 261 +15
Author merged PRs 676 -20
Test files changed Yes -10
Final score -9

Applied label: complexity: low


Changed test gate

Changed Test Gate is pending. The Changed Test Gate / changed-tests check will update the test label when it completes.

@coderabbitai

coderabbitai Bot commented Jul 28, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 95af0d10-67f4-41cc-901d-6ce16cb0e5fe

📥 Commits

Reviewing files that changed from the base of the PR and between bf2a288 and cd6f096.

📒 Files selected for processing (3)
  • .changeset/rich-rats-admire.md
  • stores/libsql/src/storage/factory-storage.test.ts
  • stores/libsql/src/storage/factory-storage.ts

Walkthrough

Changes

LibSQL write serialization

Layer / File(s) Summary
Write-gated storage operations
stores/libsql/src/storage/factory-storage.ts
Replaces the local mutex with a write gate covering insert, upsert, update, delete, and atomic update operations.
Client-level transaction wiring
stores/libsql/src/storage/factory-storage.ts
Applies client-level locking to factory transactions and disables nested locking for transaction-scoped operations.
Shared-client write-lock tests and release note
stores/libsql/src/storage/factory-storage.test.ts, .changeset/rich-rats-admire.md
Tests concurrent transactions, autocommit writes during rollback, and Experiments-domain writes; records a patch changeset.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Suggested labels: tests: green ✅

Suggested reviewers: nikaiyer, abhiaiyer91

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: serializing LibSQL Factory writes on shared clients.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/factory-libsql-write-contention

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

@dane-ai-mastra dane-ai-mastra Bot added the tests: green ✅ Changed tests failed against base as expected label Jul 28, 2026
@wardpeet
wardpeet merged commit e075db9 into main Jul 28, 2026
70 of 76 checks passed
@wardpeet
wardpeet deleted the fix/factory-libsql-write-contention branch July 28, 2026 12:42

This branch was successfully deployed

2 active deployments
Preview – mastra-playground-ui — cd6f096e Deployed Jul 28, 2026 by vercel[bot]
Preview – mastra-docs-1.x — cd6f096e Deployed Jul 28, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

complexity: low Low-complexity PR is-contributor PR author is a member of the repository organization tests: green ✅ Changed tests failed against base as expected

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants