-
Notifications
You must be signed in to change notification settings - Fork 237
Add Cloudflare Workers community world to worlds manifest #1477
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
ataylorme
wants to merge
5
commits into
vercel:main
Choose a base branch
from
ataylorme:add-cloudflare-world
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+136
−1
Open
Changes from all commits
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
34eaa93
Add Cloudflare Workers community world
ataylorme f279d75
Add Cloudflare Workers community world (fix formatting)
ataylorme c32a34e
Add cloudflare-world to docs navigation
ataylorme e4ff672
Add Cloudflare Workers world documentation page
ataylorme 15f4ceb
Point Cloudflare world docs to in-repo docs page
ataylorme File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,121 @@ | ||
| --- | ||
| title: Cloudflare Workers World | ||
| description: Community world using Durable Objects, D1, and Cloudflare Queues. | ||
| type: integration | ||
| summary: Deploy workflows to Cloudflare Workers using Durable Objects for state, D1 for indexing, and Queues for dispatch. | ||
| prerequisites: | ||
| - /docs/deploying | ||
| related: | ||
| - /docs/deploying/world/local-world | ||
| - /docs/deploying/world/vercel-world | ||
| - /docs/deploying/world/postgres-world | ||
| --- | ||
|
|
||
| The Cloudflare Workers World is a community-maintained backend that runs workflows on [Cloudflare's edge network](https://workers.cloudflare.com). It uses three Cloudflare primitives for a fully serverless architecture: | ||
|
|
||
| - **Durable Objects** for per-run state (events, steps, hooks, waits, streams) | ||
| - **D1 (SQLite)** for cross-run index queries | ||
| - **Cloudflare Queues** for reliable message dispatch | ||
|
|
||
| <Callout type="info"> | ||
| This is a community World maintained at [`@ataylorme/workflow-world-cloudflare`](https://github.com/ataylorme/workflow-world-cloudflare). For issues and contributions, visit the [GitHub repository](https://github.com/ataylorme/workflow-world-cloudflare). | ||
| </Callout> | ||
|
|
||
| ## Installation | ||
|
|
||
| Install the package: | ||
|
|
||
| ```package-install | ||
| @ataylorme/workflow-world-cloudflare | ||
| ``` | ||
|
|
||
| ## Cloudflare Bindings | ||
|
|
||
| Configure your `wrangler.toml` with the required bindings: | ||
|
|
||
| ```toml title="wrangler.toml" | ||
| name = "my-workflow-worker" | ||
| main = "src/worker.ts" | ||
| compatibility_date = "2024-12-01" | ||
|
|
||
| [durable_objects] | ||
| bindings = [ | ||
| { name = "WORKFLOW_RUNS", class_name = "WorkflowRunDO" } | ||
| ] | ||
|
|
||
| [[d1_databases]] | ||
| binding = "WORKFLOW_DB" | ||
| database_name = "workflow" | ||
| database_id = "<your-d1-database-id>" | ||
|
|
||
| [[queues.producers]] | ||
| binding = "WORKFLOW_QUEUE" | ||
| queue = "workflow-jobs" | ||
|
|
||
| [[queues.consumers]] | ||
| queue = "workflow-jobs" | ||
| max_batch_size = 10 | ||
| max_retries = 3 | ||
|
|
||
| [[migrations]] | ||
| tag = "v1" | ||
| new_classes = ["WorkflowRunDO"] | ||
| ``` | ||
|
|
||
| ## Database Migration | ||
|
|
||
| Run the D1 migration to create index tables. This is idempotent and safe to run multiple times: | ||
|
|
||
| ```ts | ||
| import { migrate } from '@ataylorme/workflow-world-cloudflare/d1'; | ||
|
|
||
| await migrate(env.WORKFLOW_DB); | ||
| ``` | ||
|
|
||
| ## Usage | ||
|
|
||
| Create the world in your Worker and re-export the Durable Object class: | ||
|
|
||
| ```ts title="src/worker.ts" lineNumbers | ||
| import { createWorld, WorkflowRunDO } from '@ataylorme/workflow-world-cloudflare'; | ||
|
|
||
| // Re-export the DO class so Cloudflare can instantiate it | ||
| export { WorkflowRunDO }; | ||
|
|
||
| export default { | ||
| async fetch(request, env) { | ||
| const world = createWorld({ | ||
| db: env.WORKFLOW_DB, | ||
| runs: env.WORKFLOW_RUNS, | ||
| queue: env.WORKFLOW_QUEUE, | ||
| }); | ||
| // Use world with your workflow runtime... | ||
| }, | ||
|
|
||
| async queue(batch, env) { | ||
| const world = createWorld({ | ||
| db: env.WORKFLOW_DB, | ||
| runs: env.WORKFLOW_RUNS, | ||
| queue: env.WORKFLOW_QUEUE, | ||
| }); | ||
| await world.handleQueueBatch(batch); | ||
| }, | ||
| }; | ||
| ``` | ||
|
|
||
| ## How It Works | ||
|
|
||
| Each workflow run maps 1:1 to a Durable Object instance. All per-run state lives in the DO's transactional storage, which provides strong consistency without external databases. | ||
|
|
||
| D1 maintains a lightweight global index so that cross-run queries (`runs.list`, `hooks.getByToken`) work without needing to fan out to every DO. The DO writes index updates to D1 fire-and-forget after each mutation. | ||
|
|
||
| Workflow and step invocations are dispatched through Cloudflare Queues for reliable, at-least-once delivery. | ||
|
|
||
| ## Limitations | ||
|
|
||
| - **`events.listByCorrelationId()`** — Requires `runId` context; the DO-per-run architecture cannot query across runs without knowing which DO to target | ||
| - **`steps.get()`** — Requires `runId` for the same routing reason | ||
| - **`readFromStream()`** — Expects stream names in `runId:streamName` format because the Streamer interface does not pass `runId` for reads | ||
| - **Cloudflare platform** — Requires Cloudflare Workers with Durable Objects, D1, and Queues enabled | ||
|
|
||
| For local development, use the [Local World](/worlds/local) which requires no external services. | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,4 +1,4 @@ | ||
| { | ||
| "title": "World", | ||
| "pages": ["local-world", "vercel-world", "postgres-world"] | ||
| "pages": ["local-world", "vercel-world", "postgres-world", "cloudflare-world"] | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
just left similar comments on a different community world PR - we need better explanation in the docs but essentially
for community worlds, the docs don't come from a markdown on our site. we currently simply link out to your readme and that's all automatically generated from the worlds-manifest
you can see an example of how the community world will look (https://useworkflow.dev/worlds/redis). This way you can keep the docs upto date on your README easily.
so adding to the worlds-manifest is enough to be added to the list. Additionally, we can setup e2e testing and benchmarking here so that those results are tracked and published to the docs site
the ones like surreal/redis/etc. all run inside github CI environment. but for cloudflare, I suppose we will need to run your world on a cf account we control for.
Let's get this added to the manifest first in this PR (please remove the docs changes - just the manifest) and I'll figure out the CI environment/setup soon after by following your README so we can start tracking and reporting it :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you can copy the jazz example from manifest where we also only list it rn but don't have a CI env setup yet for it - preview