Skip to content

fix: retry on stream_version race in event store#1571

Open
sfncore wants to merge 1 commit intopingdotgg:mainfrom
sfncore:fix/event-store-version-race
Open

fix: retry on stream_version race in event store#1571
sfncore wants to merge 1 commit intopingdotgg:mainfrom
sfncore:fix/event-store-version-race

Conversation

@sfncore
Copy link
Copy Markdown

@sfncore sfncore commented Mar 30, 2026

Summary

  • Fixes race condition in OrchestrationEventStore.append where concurrent appends to the same stream compute identical stream_version via subquery, causing UNIQUE constraint violations
  • Adds optimistic retry (up to 3 attempts) on ConstraintError so the losing writer re-reads the incremented version and succeeds

Test plan

  • Verify concurrent event appends to the same thread no longer produce PersistenceSqlError: UNIQUE constraint failed
  • Confirm single-writer append behavior is unchanged (no unnecessary retries)

🤖 Generated with Claude Code


Note

Medium Risk
Touches the event persistence write path and changes behavior under contention by retrying inserts, which could mask unexpected constraint failures if mis-scoped. Retry is bounded (3 attempts) and limited to SQL constraint errors, keeping overall risk moderate.

Overview
Improves robustness of event appends under concurrency. OrchestrationEventStore.append now retries the insert up to 3 times when the database returns a SQL ConstraintError, reducing failures from races where concurrent writers compute the same stream_version.

Non-constraint SQL and decode errors are still surfaced via the existing error mapping; only qualifying constraint failures trigger the retry.

Written by Cursor Bugbot for commit 75247d3. This will update automatically on new commits. Configure here.

Note

Retry up to 3 times on ConstraintError in makeEventStore.append

Adds an Effect.retry stage in OrchestrationEventStore.ts to handle stream_version race conditions. When an INSERT fails with a SqlError wrapping a ConstraintError, the append is retried up to 3 times before propagating the error.

Macroscope summarized 75247d3.

The stream_version is computed via subquery (SELECT max + 1), so two
concurrent appends to the same stream both read the same max version
and the second hits the UNIQUE constraint. Add optimistic retry (up to
3 attempts) on ConstraintError so the loser re-reads the incremented
version and succeeds.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 30, 2026

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 731453c0-b3f1-4ff7-a212-81706d250eda

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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 and usage tips.

@github-actions github-actions bot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:XS 0-9 changed lines (additions + deletions). labels Mar 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XS 0-9 changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants