Skip to content

Commit 2cb3bf2

Browse files
committed
commit
1 parent 4033935 commit 2cb3bf2

28 files changed

+1179
-0
lines changed
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
---
2+
link: "/workflows/platform/changelog/"
3+
productName: Workflows
4+
productLink: "/workflows/"
5+
productArea: Developer platform
6+
productAreaLink: /workflows/
7+
entries:
8+
- publish_date: "2038-01-19"
9+
title: Workflows is now in public beta.
10+
description: |-
11+
Workflows, a new product for building reliable, multi-step workflows using Cloudflare Workers, is now in public beta. The public beta is avaiable to any user with a [free or paid Workers plan](/workers/platform/pricing/).
12+
13+
A Workflow allows you to define multiple, independent steps that encapsulate errors, automatically retry, persist state, and can run for seconds, minutes, hours or even days. A Workflow can be useful for post-processing data from R2 buckets before querying it, automating a [Workers AI RAG pipeline](/workers-ai/tutorials/build-a-retrieval-augmented-generation-ai/), or managing user signup flows and lifecycle emails.
14+
15+
You can learn more about Workflows in [our announcement blog], or start building in our [get started guide].
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
---
2+
title: Dynamic steps
3+
pcx_content_type: concept
4+
sidebar:
5+
order: 5
6+
7+
---
8+
9+
A Workflow does not have to define all of its steps statically: steps can be created programmatically and/or conditionally.
10+
11+
This allows you to not only trigger steps based on specific input parameters, but to also name steps dynamically, set the retry configuration for a step
12+
13+
14+
## Example
15+
16+
Steps can be created on-the-fly, allowing you create a step for each parameter passed to your Workflow, for each file you want to read from storage, or for calls to third-party APIs.
17+
18+
For example, you can loop over each event, label the step dynamically, and have the step operate only over that `event`:
19+
20+
```ts
21+
export class MyWorkflow extends Workflow<Env, Params> {
22+
async run(events: WorkflowEvent[], step: WorkflowStep) {
23+
// Dynamically create a step for each event passed to our workflow
24+
// ... or for every file we want to read from R2 storage
25+
// ... or each API call we need to make based on an incoming request
26+
for (const event of events) {
27+
await step.do(`processing ${event.id}`, async () => {
28+
// Step logic for one event goes here
29+
// You can also specify a StepConfig for each step, just as you
30+
// would for any other step
31+
})
32+
}
33+
}
34+
}
35+
```
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
---
2+
title: Build with Workflows
3+
pcx_content_type: navigation
4+
sidebar:
5+
order: 1
6+
7+
---
8+
9+
import { DirectoryListing } from "~/components"
10+
11+
<DirectoryListing />
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
---
2+
title: Retrying
3+
pcx_content_type: concept
4+
sidebar:
5+
order: 4
6+
7+
---
8+
9+
TODO
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
---
2+
title: Rules of Steps
3+
pcx_content_type: concept
4+
sidebar:
5+
order: 10
6+
7+
---
8+
9+
A Workflow step is self-contained, individually retriable component of a Workflow. Steps may emit (optional) state that allows a Workflow to persist and continue from that step, even if a Workflow fails due to a network or infrastructure issue. A Workflow is comprised of one or more steps.
10+
11+
### Ensure API calls are idempotent
12+
13+
TODO
14+
15+
### Don't rely on state outside of a step
16+
17+
TODO
18+
19+
### Set sensible retry parameters
20+
21+
TODO
22+
23+
### Name your steps clearly
24+
25+
TODO
26+
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
---
2+
title: Trigger Workflows
3+
pcx_content_type: concept
4+
sidebar:
5+
order: 3
6+
7+
---
8+
9+
TODO - intro
10+
11+
## Workers API (Bindings)
12+
13+
You can interact with Workflows programmatically from any Worker script by creating a binding to a Workflow. A Worker can bind to multiple Workflows, including Workflows defined in other Workers projects (scripts) within your account.
14+
15+
You can interact with a Workflow:
16+
17+
* Directly over HTTP via the [`fetch`](/workers/runtime-apis/handlers/fetch/) handler
18+
* From a [Queue consumer](/queues/configuration/javascript-apis/#consumer) inside a `queue` handler
19+
* From a [Cron Trigger](/workers/configuration/cron-triggers/) inside a `scheduled` handler
20+
* Within a [Durable Object](/durable-objects/).
21+
22+
:::note
23+
24+
New to Workflows? Start with the [Workflows tutorial](/workflows/get-started/guide/) to deploy your first Workflow and familiarize yourself with Workflows concepts.
25+
26+
:::
27+
28+
To bind to a Workflow from your Workers code, you need to define a [binding](/workers/wrangler/configuration/) to a specific Workflow. For example, to bind to the Workflow defined in the [get started guide](/workflows/get-started/guide/), you would configure a `wrangler.toml` with the below:
29+
30+
```toml title="wrangler.toml"
31+
name = "workflows-tutorial"
32+
main = "src/index.ts"
33+
compatibility_date = "2024-10-15"
34+
35+
[[workflows]]
36+
# The name of the Workflow
37+
name = "workflows-tutorial"
38+
# The binding name, which must be a valid JavaScript variable name. This will
39+
# be how you call (run) your Workflow from your other Workers handlers or
40+
# scripts.
41+
binding = "MY_WORKFLOW"
42+
# script_name is required during for the beta.
43+
# Must match the "name" of your Worker at the top of wrangler.toml
44+
script_name = "workflows-tutorial"
45+
# Must match the class defined in your code that extends the Workflow class
46+
class_name = "MyWorkflow"
47+
```
48+
49+
The `binding = "MY_WORKFLOW"` line defines the JavaScript variable that our Workflow methods are accessible on, including `create` (which triggers a new instance) or `get` (which returns the status of an existing instance).
50+
51+
```ts title="src/index.ts"
52+
interface Env {
53+
MY_WORKFLOW: Workflow;
54+
}
55+
56+
export default {
57+
async fetch(req: Request, env: Env) {
58+
//
59+
const instanceId = new URL(req.url).searchParams.get("instanceId")
60+
61+
// If an ?instanceId=<id> query parameter is provided, fetch the status
62+
// of an existing Workflow by its ID.
63+
if (instanceId) {
64+
let instance = await env.MY_WORKFLOW.get(id);
65+
return Response.json({
66+
status: await instance.status(),
67+
});
68+
}
69+
70+
// Else, create a new instance of our Workflow, passing in any (optional) params
71+
// and return the ID.
72+
const newId = await crypto.randomUUID();
73+
let instance = await env.MY_WORKFLOW.create(newId, {});
74+
return Response.json({
75+
id: instance.id,
76+
details: await instance.status(),
77+
});
78+
79+
return Response.json({ result });
80+
},
81+
};
82+
```
83+
84+
## REST API (HTTP)
85+
86+
TODO
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
---
2+
title: Dynamic steps
3+
pcx_content_type: concept
4+
sidebar:
5+
order: 6
6+
7+
---
8+
9+
TODO - outline how to use TypeScript and
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
---
2+
title: Workers API
3+
pcx_content_type: concept
4+
sidebar:
5+
order: 2
6+
7+
---
8+
9+
TODO
10+
11+
12+
## Interacting with Workflows
13+
14+
* Running a Workflow with the `run()` method
15+
* `StepConfig`
16+
* `NonRetriableError`
17+
* TODO on TypeScript type params
18+
19+
## Workflow
20+
21+
* <code>run(events: WorkflowEvent&lt;T&gt;[], step: WorkflowStep): Promise&lt;T&gt;</code>
22+
23+
TODO
24+
25+
```ts
26+
export class MyWorkflow extends Workflow<Env, Params> {
27+
async run(events: WorkflowEvent[], step: WorkflowStep) {
28+
// TODO
29+
}
30+
}
31+
```
32+
33+
34+
## WorkflowStep
35+
36+
### step
37+
38+
TODO - into to steps
39+
40+
* <code>step.do(name: string, callback: (): RpcSerializable, config?: StepConfig): Promise&lt;T&gt;</code>
41+
42+
* TODO - describe each param
43+
* TODO -
44+
45+
TODO - show an example
46+
TODO - show an example of dynamically creating a step
47+
48+
* <code>step.sleep(name: string, duration: WorkflowDuration): Promise&lt;void&gt;</code>
49+
50+
* TODO -
51+
52+
TODO - show an example
53+
54+
55+
## StepConfig
56+
57+
TODO
58+
59+
## NonRetriableError
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
---
2+
type: example
3+
summary: Automate lifecycle emails
4+
tags:
5+
- Workflows
6+
- Email
7+
pcx_content_type: configuration
8+
title: Automate lifecycle emails
9+
sidebar:
10+
order: 3
11+
description: Automate lifecycle emails using Workflows and Resend
12+
13+
---
14+
15+
import { TabItem, Tabs } from "~/components"
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
---
2+
type: overview
3+
hideChildren: false
4+
pcx_content_type: navigation
5+
title: Examples
6+
sidebar:
7+
order: 6
8+
9+
---
10+
11+
import { GlossaryTooltip, ListExamples } from "~/components"
12+
13+
Explore the following <GlossaryTooltip term="code example">examples</GlossaryTooltip> for D1.
14+
15+
<ListExamples directory="d1/examples/" />

0 commit comments

Comments
 (0)