You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Materialize waits as entities to prevent duplicate wait_completed events (#1057)
* Handle 409 conflict when completing waits that were already completed
When multiple concurrent workflow invocations race to complete the same
wait, the server returns 409 (conflict) for duplicates. This change
handles the 409 gracefully in both runtime.ts (sleep elapsed check) and
runs.ts (wakeUpRun), preventing crashes and treating already-completed
waits as successful.
Also updates event-sourcing docs to reflect that waits are now
materialized as entities in storage with atomic completion guarantees.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Point e2e tests at workflow-server preview for wait materialization branch
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Materialize waits as entities in local and postgres worlds to prevent duplicate wait_completed events
Adds Wait type/schema to the shared world package and implements wait entity
materialization in both local (filesystem) and postgres world implementations,
matching the DynamoDB behavior. wait_created creates a wait entity with status
'waiting', and wait_completed transitions it to 'completed' with guards that
reject duplicates (409).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Fix waitId to use composite key for consistency with postgres world
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Clean up wait entities on terminal run states and register waits migration
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Clear WORKFLOW_SERVER_URL_OVERRIDE for merge
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Update changeset for all affected packages and restore server URL override
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Clear WORKFLOW_SERVER_URL_OVERRIDE now that server PR is merged
The server-side changes (vercel/workflow-server#265) have been merged to main
and deployed to production, so we no longer need to point at the preview URL.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Materialize waits as entities to prevent duplicate wait_completed events
9
+
10
+
-`@workflow/core`: Handle 409 conflict gracefully when creating wait_completed events, preventing crashes when multiple concurrent invocations race to complete the same wait
11
+
-`@workflow/world`: Add `Wait` type, `WaitSchema`, and `WaitStatusSchema` exports; add optional `wait` field to `EventResult`
12
+
-`@workflow/world-local`: Materialize wait entities on wait_created/wait_completed with duplicate detection; clean up waits on terminal run states
13
+
-`@workflow/world-postgres`: Add `workflow_waits` table with `wait_status` enum; materialize wait entities with conditional writes for duplicate prevention; clean up waits on terminal run states
Copy file name to clipboardExpand all lines: docs/content/docs/how-it-works/event-sourcing.mdx
+2-2Lines changed: 2 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -33,7 +33,7 @@ In the Workflow DevKit, the following entity types are managed through events:
33
33
-**Runs**: Workflow execution instances (materialized in storage)
34
34
-**Steps**: Individual atomic operations within a workflow (materialized in storage)
35
35
-**Hooks**: Suspension points that can receive external data (materialized in storage)
36
-
-**Waits**: Sleep or delay operations (tracked via events only, not materialized)
36
+
-**Waits**: Sleep or delay operations (materialized in storage)
37
37
38
38
## Entity Lifecycles
39
39
@@ -151,7 +151,7 @@ flowchart TD
151
151
-`completed`: Delay period has elapsed, workflow can resume
152
152
153
153
<Callouttype="info">
154
-
Unlike Runs, Steps, and Hooks, waits are conceptual entities tracked only through events. There is no separate "Wait" record in storage that can be queried—the wait state is derived entirely from the `wait_created` and `wait_completed` events in the event log.
154
+
Like Runs, Steps, and Hooks, waits are materialized as entities in storage. When a `wait_created` event is processed, a wait entity is created with status `waiting`. When a `wait_completed` event is processed, the wait entity is atomically transitioned to `completed` — this guarantees that a wait can only be completed exactly once, even if multiple concurrent invocations attempt to complete it simultaneously.
0 commit comments