mirror of
https://github.com/ksyasuda/dotfiles.git
synced 2026-03-21 18:11:27 -07:00
update skills
This commit is contained in:
@@ -0,0 +1,151 @@
|
||||
# Workflow Configuration
|
||||
|
||||
## wrangler.jsonc Setup
|
||||
|
||||
```jsonc
|
||||
{
|
||||
"name": "my-worker",
|
||||
"main": "src/index.ts",
|
||||
"compatibility_date": "2025-01-01", // Use current date for new projects
|
||||
"observability": {
|
||||
"enabled": true // Enables Workflows dashboard + structured logs
|
||||
},
|
||||
"workflows": [
|
||||
{
|
||||
"name": "my-workflow", // Workflow name
|
||||
"binding": "MY_WORKFLOW", // Env binding
|
||||
"class_name": "MyWorkflow" // TS class name
|
||||
// "script_name": "other-worker" // For cross-script calls
|
||||
}
|
||||
],
|
||||
"limits": {
|
||||
"cpu_ms": 300000 // 5 min max (default 30s)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Step Configuration
|
||||
|
||||
```typescript
|
||||
// Basic step
|
||||
const data = await step.do('step name', async () => ({ result: 'value' }));
|
||||
|
||||
// With retry config
|
||||
await step.do('api call', {
|
||||
retries: {
|
||||
limit: 10, // Default: 5, or Infinity
|
||||
delay: '10 seconds', // Default: 10000ms
|
||||
backoff: 'exponential' // constant | linear | exponential
|
||||
},
|
||||
timeout: '30 minutes' // Per-attempt timeout (default: 10min)
|
||||
}, async () => {
|
||||
const res = await fetch('https://api.example.com/data');
|
||||
if (!res.ok) throw new Error('Failed');
|
||||
return res.json();
|
||||
});
|
||||
```
|
||||
|
||||
### Parallel Steps
|
||||
```typescript
|
||||
const [user, settings] = await Promise.all([
|
||||
step.do('fetch user', async () => this.env.KV.get(`user:${id}`)),
|
||||
step.do('fetch settings', async () => this.env.KV.get(`settings:${id}`))
|
||||
]);
|
||||
```
|
||||
|
||||
### Conditional Steps
|
||||
```typescript
|
||||
const config = await step.do('fetch config', async () =>
|
||||
this.env.KV.get('flags', { type: 'json' })
|
||||
);
|
||||
|
||||
// ✅ Deterministic (based on step output)
|
||||
if (config.enableEmail) {
|
||||
await step.do('send email', async () => sendEmail());
|
||||
}
|
||||
|
||||
// ❌ Non-deterministic (Date.now outside step)
|
||||
if (Date.now() > deadline) { /* BAD */ }
|
||||
```
|
||||
|
||||
### Dynamic Steps (Loops)
|
||||
```typescript
|
||||
const files = await step.do('list files', async () =>
|
||||
this.env.BUCKET.list()
|
||||
);
|
||||
|
||||
for (const file of files.objects) {
|
||||
await step.do(`process ${file.key}`, async () => {
|
||||
const obj = await this.env.BUCKET.get(file.key);
|
||||
return processData(await obj.arrayBuffer());
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
## Multiple Workflows
|
||||
|
||||
```jsonc
|
||||
{
|
||||
"workflows": [
|
||||
{"name": "user-onboarding", "binding": "USER_ONBOARDING", "class_name": "UserOnboarding"},
|
||||
{"name": "data-processing", "binding": "DATA_PROCESSING", "class_name": "DataProcessing"}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
Each class extends `WorkflowEntrypoint` with its own `Params` type.
|
||||
|
||||
## Cross-Script Bindings
|
||||
|
||||
Worker A defines workflow. Worker B calls it by adding `script_name`:
|
||||
|
||||
```jsonc
|
||||
// Worker B (caller)
|
||||
{
|
||||
"workflows": [{
|
||||
"name": "billing-workflow",
|
||||
"binding": "BILLING",
|
||||
"script_name": "billing-worker" // Points to Worker A
|
||||
}]
|
||||
}
|
||||
```
|
||||
|
||||
## Bindings
|
||||
|
||||
Workflows access Cloudflare bindings via `this.env`:
|
||||
|
||||
```typescript
|
||||
type Env = {
|
||||
MY_WORKFLOW: Workflow;
|
||||
KV: KVNamespace;
|
||||
DB: D1Database;
|
||||
BUCKET: R2Bucket;
|
||||
AI: Ai;
|
||||
VECTORIZE: VectorizeIndex;
|
||||
};
|
||||
|
||||
await step.do('use bindings', async () => {
|
||||
const kv = await this.env.KV.get('key');
|
||||
const db = await this.env.DB.prepare('SELECT * FROM users').first();
|
||||
const file = await this.env.BUCKET.get('file.txt');
|
||||
const ai = await this.env.AI.run('@cf/meta/llama-2-7b-chat-int8', { prompt: 'Hi' });
|
||||
});
|
||||
```
|
||||
|
||||
## Pages Functions Binding
|
||||
|
||||
Pages Functions can trigger Workflows via service bindings:
|
||||
|
||||
```typescript
|
||||
// functions/_middleware.ts
|
||||
export const onRequest: PagesFunction<Env> = async ({ env, request }) => {
|
||||
const instance = await env.MY_WORKFLOW.create({
|
||||
params: { url: request.url }
|
||||
});
|
||||
return new Response(`Started ${instance.id}`);
|
||||
};
|
||||
```
|
||||
|
||||
Configure in wrangler.jsonc under `service_bindings`.
|
||||
|
||||
See: [api.md](./api.md), [patterns.md](./patterns.md)
|
||||
Reference in New Issue
Block a user