Skip to content

feat(openworkflow, dashboard, docs): add workflow signals#385

Open
jamescmartinez wants to merge 2 commits intomainfrom
signals
Open

feat(openworkflow, dashboard, docs): add workflow signals#385
jamescmartinez wants to merge 2 commits intomainfrom
signals

Conversation

@jamescmartinez
Copy link
Contributor

@jamescmartinez jamescmartinez commented Mar 16, 2026

🚧 wip

This PR adds workflow signal support so runs can durably wait events and resume when a matching signal arrives.

Signals are workflow run-addressed and durably buffered (not waiter-only), which means a signal can be sent before a workflow reaches waitForSignal(), and it will still be delivered after replay/restart.

Changes

  • ow.sendSignal(), step.sendSignal(), and step.waitForSignal()
  • Persist and consume signals in SQLite/Postgres (w/ migrations)
  • Update docs

Copilot AI review requested due to automatic review settings March 16, 2026 19:17
@pkg-pr-new
Copy link

pkg-pr-new bot commented Mar 16, 2026

Open in StackBlitz

npm i https://pkg.pr.new/openworkflowdev/openworkflow/@openworkflow/cli@385
npm i https://pkg.pr.new/openworkflowdev/openworkflow/@openworkflow/dashboard@385
npm i https://pkg.pr.new/openworkflowdev/openworkflow@385

commit: dd5022a

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds first-class “workflow signals” to OpenWorkflow so runs can durably wait for external/workflow-originated events and resume from buffered delivery after replay/restart.

Changes:

  • Introduce ow.sendSignal(), step.sendSignal(), and step.waitForSignal() with durable buffering + schema validation + timeout behavior.
  • Persist/consume buffered signals in both SQLite and Postgres backends (including migrations) and update run wake-up logic to account for pending signals.
  • Expand docs, architecture notes, dashboard labeling, and add comprehensive tests across worker + backend + client.

Reviewed changes

Copilot reviewed 24 out of 24 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
packages/openworkflow/worker/execution.ts Implements step.sendSignal / step.waitForSignal, tracks active signal waits, and integrates wait timeouts into sleep/resume logic.
packages/openworkflow/worker/execution.test.ts Adds worker-level integration tests for buffering, parking/resume, timeout, schema failure, and concurrency rejection.
packages/openworkflow/testing/backend.testsuite.ts Adds backend conformance tests for signal FIFO buffering, idempotency, wake behavior, and error cases.
packages/openworkflow/sqlite/sqlite.ts Adds SQLite migration for workflow_signals table + indexes.
packages/openworkflow/sqlite/sqlite.test.ts Verifies migrations create workflow_signals and migrate() applies it.
packages/openworkflow/sqlite/backend.ts Implements SQLite sendWorkflowSignal / consumeWorkflowSignal and wake reconciliation for parked signal waits.
packages/openworkflow/postgres/postgres.ts Adds Postgres migration for workflow_signals table + indexes.
packages/openworkflow/postgres/postgres.test.ts Asserts latest migration includes workflow_signals.
packages/openworkflow/postgres/backend.ts Implements Postgres sendWorkflowSignal / consumeWorkflowSignal and wake reconciliation for parked signal waits.
packages/openworkflow/core/workflow-function.ts Extends StepApi with signal methods and introduces StepWaitTimeout.
packages/openworkflow/core/step-attempt.ts Adds new step kinds (signal-send, signal-wait) and a persisted signal-wait context helper.
packages/openworkflow/core/step-attempt.test.ts Tests createSignalWaitContext.
packages/openworkflow/core/backend.ts Extends backend interface with signal send/consume APIs.
packages/openworkflow/client/client.ts Adds OpenWorkflow.sendSignal() client API (with optional idempotency key).
packages/openworkflow/client/client.test.ts Tests client forwards signals to backend.
packages/docs/docs/workflows.mdx Documents external sends via ow.sendSignal() and updates StepApi description.
packages/docs/docs/steps.mdx Documents new step types (step.sendSignal, step.waitForSignal).
packages/docs/docs/signals.mdx New end-to-end Signals documentation page.
packages/docs/docs/roadmap.mdx Marks Signals as completed.
packages/docs/docs/overview.mdx Updates overview to mention durable signal waiting.
packages/docs/docs/openworkflow-vs-temporal.mdx Updates feature comparison now that signals exist.
packages/docs/docs.json Adds Signals page to docs nav.
packages/dashboard/src/routes/runs/$runId.tsx Improves display label for new step kinds and adds “Step Kind” metadata field.
ARCHITECTURE.md Documents workflow_signals table and signal step APIs/semantics.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@codecov
Copy link

codecov bot commented Mar 16, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

Copilot AI review requested due to automatic review settings March 16, 2026 21:18
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR adds durable workflow signal support so workflow runs can buffer external events and resume deterministically when step.waitForSignal() consumes a matching signal.

Changes:

  • Adds ow.sendSignal(), step.sendSignal(), and step.waitForSignal() APIs (including schema validation + timeouts).
  • Persists buffered signals in new workflow_signals tables (SQLite/Postgres) and wakes parked runs when signals arrive.
  • Updates dashboard labeling and docs/architecture to describe signal behavior.

Reviewed changes

Copilot reviewed 26 out of 26 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
packages/openworkflow/worker/execution.ts Implements step.sendSignal() / step.waitForSignal() and integrates signal-wait into wake-up logic.
packages/openworkflow/worker/execution.test.ts Adds extensive unit/integration tests for signal buffering, waiting, timeouts, replay behavior.
packages/openworkflow/testing/backend.testsuite.ts Extends backend conformance tests for signal buffering, idempotency, wake behavior.
packages/openworkflow/sqlite/sqlite.ts Adds SQLite migration v5 creating workflow_signals table + indexes.
packages/openworkflow/sqlite/sqlite.test.ts Verifies migrations create workflow_signals and migrate() applies it.
packages/openworkflow/sqlite/backend.ts Implements SQLite sendWorkflowSignal / consumeWorkflowSignal and wake reconciliation for pending signals.
packages/openworkflow/sqlite/backend.test.ts Adds targeted tests for SQLite signal-send fallback/idempotency branches.
packages/openworkflow/postgres/postgres.ts Adds Postgres migration v5 creating workflow_signals table + indexes.
packages/openworkflow/postgres/postgres.test.ts Verifies latest migration includes workflow_signals.
packages/openworkflow/postgres/backend.ts Implements Postgres sendWorkflowSignal / consumeWorkflowSignal and wake reconciliation for pending signals.
packages/openworkflow/postgres/backend.test.ts Adds targeted tests for Postgres signal-send fallbacks and consume edge cases.
packages/openworkflow/core/workflow-function.ts Extends StepApi with signal methods and introduces StepWaitTimeout alias.
packages/openworkflow/core/step-attempt.ts Adds signal-send / signal-wait step kinds and createSignalWaitContext.
packages/openworkflow/core/step-attempt.test.ts Tests createSignalWaitContext.
packages/openworkflow/core/backend.ts Extends Backend interface with sendWorkflowSignal / consumeWorkflowSignal.
packages/openworkflow/client/client.ts Adds OpenWorkflow.sendSignal() client API.
packages/openworkflow/client/client.test.ts Tests OpenWorkflow.sendSignal() delegates correctly to backend.
packages/docs/docs/workflows.mdx Documents external sends via ow.sendSignal() and updates StepApi parameter table.
packages/docs/docs/steps.mdx Documents new step types for sending/waiting signals.
packages/docs/docs/signals.mdx Adds new Signals documentation page with usage + semantics.
packages/docs/docs/roadmap.mdx Marks signals as shipped.
packages/docs/docs/overview.mdx Updates overview to mention durable signal waiting.
packages/docs/docs/openworkflow-vs-temporal.mdx Updates comparison now that signals exist.
packages/docs/docs.json Adds signals page to docs navigation.
packages/dashboard/src/routes/runs/$runId.tsx Improves step kind labeling for signal steps and shows Step Kind in inspector.
ARCHITECTURE.md Updates architecture docs to include workflow_signals and signal step APIs.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@Nic13Gamer
Copy link
Contributor

Just gave the PR a quick read, in my opinion I don't think that requiring the workflow run ID to send a signal is the right approach.

In many integrations the external system already has its own identifier, and forcing the workflow run ID means we now need to maintain a mapping between the two.

For example with Resend: after sending (queuing) an email you get an ID, and their webhook (if the email was successfully sent) later sends that same ID. If signals require the workflow run ID, I now need to store a mapping between the email ID and the workflow run ID just to route the signal.

For a suggestion, I like the approach used by Upstash Workflow where you wait on an event using a user-defined ID and then notify using that same ID. The workflow just does something like waitForEvent("email-delivered", emailId) and the external system later notifies using that identifier.

@jamescmartinez
Copy link
Contributor Author

@Nic13Gamer thanks, this is really helpful feedback - it's something I've gone back and forth on.

I started with run-addressed signals because it was simplest version to ship to testers first. That said, I'm still flexible on the shape and want to see how these integration patterns show up in practice (your Resend example was great).

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.

3 participants