Skip to content

fix(world-postgres): create runs and initial events atomically - #4111

Merged
VaguelySerious merged 1 commit into
vercel:mainfrom
komly:fix/postgres-atomic-run-creation
Sep 11, 2026
Merged

VaguelySerious merged 1 commit into
vercel:mainfrom
komly:fix/postgres-atomic-run-creation

Conversation

@komly

@komly komly commented Sep 11, 2026 •

Copy link
Copy Markdown
Contributor

Description

Fixes #3656.

Create the run row, its slot marker, and the initial run_created event in one transaction at both creation sites. A concurrent writer can no longer observe a new run before its slot identity exists, and a failed initial-event insert rolls back the run and marker. Existing creator-conflict handling is preserved.

How did you test your changes?

  • Seven integration tests against an isolated local PostgreSQL 18.2 database, using the package migrations. Four lock barriers cover visibility before the marker and before the first event for both creation paths; two check rollback on a real constraint violation; one checks duplicate creation. Unmodified main fails six tests and passes the duplicate test; the fix passes all seven.
  • Existing package source tests: 27 passed.
  • Package build passed with Node 24.21.0 and pnpm 11.24.0.
  • Biome: no errors (existing complexity and non-null assertion warnings remain). Changeset status and git diff --check passed.

The new test file uses Testcontainers by default and accepts an explicit loopback WORKFLOW_POSTGRES_URL for local development. It creates and drops only its isolated database. No mocks are added.

PR Checklist - Required to merge

  • 📦 Patch changeset included; pnpm changeset status --since=main passes.
  • 🔒 DCO sign-off included.
  • 📝 Ping @vercel/workflow in a comment once the PR is ready, and the above checklist is complete.

Diff size

Docs — 2 files · +14 / -0

Describe the atomic creation guarantee, local test command, and patch release.

Implementation — 1 file · +81 / -58

Keep both existing creation paths in a transaction through their first event; most of the diff is moving those inserts into the transaction.

Tests — 1 file · +169 / -0

Use real PostgreSQL locks and constraint failures to verify visibility, rollback, and duplicate creation.

@komly
komly requested a review from a team as a code owner September 11, 2026 18:12
@changeset-bot

changeset-bot Bot commented Sep 11, 2026 •

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 561ffa1

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

This PR includes changesets to release 1 package
Name Type
@workflow/world-postgres 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 Sep 11, 2026

Copy link
Copy Markdown
Contributor

@komly is attempting to deploy a commit to the Vercel Labs Team on Vercel.

A member of the Team first needs to authorize it.

@komly

komly commented Sep 11, 2026

Copy link
Copy Markdown
Contributor Author

@vercel/workflow Ready for review. This fixes #3656 with seven real-PostgreSQL regression cases (six fail on the upstream base), a patch changeset, and a verified, DCO-signed commit.

Comment thread packages/world-postgres/README.md Outdated
## Features

- **Durable storage**: Stores workflow runs, events, steps, hooks, and webhooks in PostgreSQL
- **Atomic run creation**: A new run becomes visible together with its event slot marker and initial `run_created` event, including when a queued `run_started` creates the run.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove all the changes in this file

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(AI) Reverted in cef47e2. Since that removed the documented WORKFLOW_POSTGRES_URL path, I also rewrote run-creation.test.ts to follow the setup of the other world-postgres integration tests (Testcontainers plus pnpm db:push, in-describe win32 skip). Verified the rewritten file still fails 6/7 on main and passes 7/7 with the fix; the full world-postgres suite (219 tests) passes on the branch.

'@workflow/world-postgres': patch
---

Create a workflow run, its slot marker, and its first event in one transaction so concurrent execution and interrupted creation cannot observe partial runs.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Create a workflow run, its slot marker, and its first event in one transaction so concurrent execution and interrupted creation cannot observe partial runs.
Fix run creation and slot allocation not happening transactionally

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(AI) Applied in cef47e2.

@VaguelySerious

Copy link
Copy Markdown
Member

(AI) Pushed cef47e2 addressing the review comments (changeset wording, README reverted, test aligned with the other world-postgres integration tests). Full world-postgres suite passes on the branch (219 tests).

Additional validation, not committed: a live creation storm (60 run ids, each hit by 3 concurrent run_created and 3 resilient run_started from separate connections) produced no errors other than EntityConflictError on this branch, no duplicate run_created, and no legacy wevt_ ids. It also did not reproduce the window on unmodified main, so the lock-barrier tests in this PR are the right way to pin the behavior.

One note, not blocking: run creation now costs BEGIN/COMMIT round trips around the three inserts (5 statements instead of 3 autocommits). Creation-only and the same shape as the existing step_started / step_created transactions.

Signed-off-by: Dmitry Petrov <Komly@yandex.ru>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: Peter Wielander <peter.wielander@vercel.com>
@VaguelySerious
VaguelySerious force-pushed the fix/postgres-atomic-run-creation branch from cef47e2 to 561ffa1 Compare September 11, 2026 20:55
@VaguelySerious
VaguelySerious merged commit 2eb2fe6 into vercel:main Sep 11, 2026
114 of 172 checks passed
github-actions Bot added a commit that referenced this pull request Sep 11, 2026
Signed-off-by: Dmitry Petrov <Komly@yandex.ru>
Co-authored-by: Peter Wielander <peter.wielander@vercel.com>
Signed-off-by: Dmitry Petrov <Komly@yandex.ru>
@github-actions

Copy link
Copy Markdown
Contributor

Backport PR opened against stable: #4132. Merge conflicts were resolved by AI — please review carefully. (backport job run)

VaguelySerious added a commit that referenced this pull request Sep 11, 2026
#4132)

Co-authored-by: Dmitry Petrov <Komly@yandex.ru>
Co-authored-by: Peter Wielander <peter.wielander@vercel.com>
@github-actions github-actions Bot mentioned this pull request Sep 11, 2026
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.

world-postgres: create run row, slot marker, and run_created event atomically

2 participants