Skip to content

Make fenced commits atomic - #45

Merged
cardmagic merged 5 commits into
mainfrom
fix/atomic-fenced-commits
Sep 9, 2026
Merged

Make fenced commits atomic#45
cardmagic merged 5 commits into
mainfrom
fix/atomic-fenced-commits

Conversation

@cardmagic

@cardmagic cardmagic commented Sep 9, 2026

Copy link
Copy Markdown
Owner

Summary

  • hold the actor instance and exact message-claim row locks from fence validation through commit on PostgreSQL and MySQL
  • make expired-lease recovery and stale-process cleanup re-read locked rows before requeueing work
  • add deterministic adapter regressions for a commit that outlives its lease and for process cleanup waiting behind an active commit
  • record the stronger fencing contract in the changelog and parity ledger
  • update Vitest and the transitive Sharp dependency after CI began rejecting newly disclosed advisories
  • prepare the package, exported runtime version, and dated changelog entry for the 0.14.8 release

Root cause

Fence validation used a plain SELECT before commit actions ran. A lease could expire while the transaction remained open, allowing another worker to recover the claim and advance the activation generation before the first worker wrote state. Recovery also acted on rows read before a lock wait, so it could requeue a message that completed while it was blocked.

Validation

  • pnpm run check
  • pnpm test (366 passed, 21 skipped)
  • PostgreSQL adapter suite (15 passed)
  • MySQL adapter suite (10 passed)
  • pnpm run pack:check (solid-objects@0.14.8)
  • pnpm run test:package
  • node scripts/release-notes.mjs 0.14.8
  • pnpm audit --audit-level=high (no known vulnerabilities)
  • pnpm peers check (no peer dependency issues)

The PostgreSQL regression failed before the fix because the replacement claim settled before the first commit was released; it passes after the row-locking change. The same post-fix interleaving passes against MySQL 8.4. The database barriers always release in cleanup and use a 15-second integration-test timeout for slower CI runners.

Lease recovery could act on stale reads while an actor commit was open.

Lock the instance and claim through completion. Revalidate lease and process cleanup candidates after lock waits.
@greptile-apps

greptile-apps Bot commented Sep 9, 2026

Copy link
Copy Markdown

Greptile Summary

The PR strengthens fenced commits by holding actor-instance and message-claim row locks through transaction completion, then revalidating locked state before lease recovery or stale-process cleanup.

  • Adds PostgreSQL and MySQL concurrency regressions for commits that outlive leases and cleanup blocked behind active commits.
  • Records the stronger fencing contract in release and parity documentation.
  • Updates the package version to 0.14.8 and refreshes Vitest and Sharp-related dependency resolutions.
  • The latest commit consistently converts the unreleased entry and package/runtime version metadata to 0.14.8.

Confidence Score: 5/5

The PR appears safe to merge, with the latest release metadata synchronized and no outstanding findings.

The current implementation locks and revalidates the durable ownership rows needed for atomic fenced commits, includes adapter-specific regression coverage, and consistently publishes version 0.14.8. Both previous review threads are resolved, and no new actionable issue was identified.

Important Files Changed

Filename Overview
src/repository.ts Holds activation and claim locks through fenced commits and revalidates rows after recovery lock waits.
test/mysql.test.ts Adds deterministic MySQL regressions for lease expiry and stale-process cleanup interleavings.
test/postgresql.test.ts Adds deterministic PostgreSQL coverage for the fenced-commit races.
test/support/fenced-commit.ts Provides shared synchronization helpers for the database concurrency regressions.
package.json Publishes version 0.14.8 and updates Vitest to 4.1.11.
pnpm-lock.yaml Resolves the Vitest update and forces affected Sharp versions to 0.35.4.
pnpm-workspace.yaml Adds the Sharp override and explicit release-age exclusions for security-driven updates.
CHANGELOG.md Documents the stronger fenced-commit contract under release 0.14.8.
src/version.ts Keeps the exported runtime version synchronized at 0.14.8.

Sequence Diagram

sequenceDiagram
  participant W as Active worker
  participant DB as Database
  participant R as Recovery worker
  W->>DB: Lock actor instance
  W->>DB: Validate activation fence
  W->>DB: Lock exact message claim
  W->>DB: Write state, result, and commit actions
  R->>DB: Wait for locked rows
  W->>DB: Commit and release locks
  R->>DB: Re-read current rows
  R-->>R: Skip requeue when claim already completed
Loading

Reviews (3): Last reviewed commit: "chore: bump version to 0.14.8" | Re-trigger Greptile

Comment thread src/repository.ts Outdated
Comment thread test/mysql.test.ts
Always release paused commits when an assertion or setup step fails.

Give real-database concurrency tests enough time on slower CI runners.
CI began rejecting newly disclosed Vitest and Sharp advisories.

Use patched test tooling and keep the Sharp override limited to vulnerable transitive versions.
Flatten activation release behind an early guard to match repository style.

Exercise the cleanup interleaving against MySQL as well as PostgreSQL.
@cardmagic

Copy link
Copy Markdown
Owner Author

@greptileai

Prepare the atomic fencing fix for release by aligning the package metadata, exported runtime version, and dated changelog entry.
@cardmagic

Copy link
Copy Markdown
Owner Author

@greptileai please review the latest commit 57d437a

@cardmagic
cardmagic merged commit aefb166 into main Sep 9, 2026
19 checks passed
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.

1 participant