@pgflow/core 0.0.0-array-map-steps-cd94242a-20251008042921 → 0.0.0-condition-4354fcb6-20260108134756
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +24 -7
- package/dist/CHANGELOG.md +187 -13
- package/dist/PgflowSqlClient.js +1 -1
- package/dist/README.md +24 -7
- package/dist/database-types.d.ts +392 -71
- package/dist/database-types.d.ts.map +1 -1
- package/dist/package.json +8 -4
- package/dist/supabase/migrations/20250429164909_pgflow_initial.sql +2 -2
- package/dist/supabase/migrations/20251006073122_pgflow_add_map_step_type.sql +24 -7
- package/dist/supabase/migrations/20251103222045_pgflow_fix_broadcast_order_and_timestamp_handling.sql +622 -0
- package/dist/supabase/migrations/20251104080523_pgflow_upgrade_pgmq_1_5_1.sql +93 -0
- package/dist/supabase/migrations/20251130000000_pgflow_auto_compilation.sql +268 -0
- package/dist/supabase/migrations/20251209074533_pgflow_worker_management.sql +273 -0
- package/dist/supabase/migrations/20251212100113_pgflow_allow_data_loss_parameter.sql +54 -0
- package/dist/supabase/migrations/20251225163110_pgflow_add_flow_input_column.sql +185 -0
- package/dist/supabase/migrations/20260103145141_pgflow_step_output_storage.sql +909 -0
- package/dist/supabase/migrations/20260108131350_pgflow_step_conditions.sql +1515 -0
- package/dist/types.d.ts +7 -4
- package/dist/types.d.ts.map +1 -1
- package/package.json +9 -5
- package/dist/ATLAS.md +0 -32
package/README.md
CHANGED
|
@@ -5,10 +5,6 @@ PostgreSQL-native workflow engine for defining, managing, and tracking DAG-based
|
|
|
5
5
|
> [!NOTE]
|
|
6
6
|
> This project and all its components are licensed under [Apache 2.0](./LICENSE) license.
|
|
7
7
|
|
|
8
|
-
> [!WARNING]
|
|
9
|
-
> This project uses [Atlas](https://atlasgo.io/docs) to manage the schemas and migrations.
|
|
10
|
-
> See [ATLAS.md](ATLAS.md) for more details.
|
|
11
|
-
|
|
12
8
|
## Table of Contents
|
|
13
9
|
|
|
14
10
|
- [Overview](#overview)
|
|
@@ -47,6 +43,16 @@ This package focuses on:
|
|
|
47
43
|
|
|
48
44
|
The actual execution of workflow tasks is handled by the [Edge Worker](../edge-worker/README.md), which calls back to the SQL Core to acknowledge task completion or failure.
|
|
49
45
|
|
|
46
|
+
## Requirements
|
|
47
|
+
|
|
48
|
+
> [!IMPORTANT] > **pgmq Version Requirement** (since v0.8.0)
|
|
49
|
+
>
|
|
50
|
+
> pgflow v0.8.0 and later requires **pgmq 1.5.0 or higher**. This version of pgflow will NOT work with pgmq 1.4.x or earlier.
|
|
51
|
+
>
|
|
52
|
+
> - **Supabase Cloud**: Recent versions include pgmq 1.5.0+ by default
|
|
53
|
+
> - **Self-hosted**: You must upgrade pgmq to version 1.5.0+ before upgrading pgflow
|
|
54
|
+
> - **Version Check**: Run `SELECT extversion FROM pg_extension WHERE extname = 'pgmq';` to verify your pgmq version
|
|
55
|
+
|
|
50
56
|
## Key Features
|
|
51
57
|
|
|
52
58
|
- **Declarative Workflows**: Define flows and steps via SQL tables
|
|
@@ -140,6 +146,7 @@ SELECT pgflow.add_step(
|
|
|
140
146
|
#### Root Map vs Dependent Map
|
|
141
147
|
|
|
142
148
|
**Root Map Steps** process the flow's input array directly:
|
|
149
|
+
|
|
143
150
|
```sql
|
|
144
151
|
-- Root map: no dependencies, processes flow input
|
|
145
152
|
SELECT pgflow.add_step(
|
|
@@ -156,6 +163,7 @@ SELECT pgflow.start_flow(
|
|
|
156
163
|
```
|
|
157
164
|
|
|
158
165
|
**Dependent Map Steps** process another step's array output:
|
|
166
|
+
|
|
159
167
|
```sql
|
|
160
168
|
-- Dependent map: processes the array from 'fetch_items'
|
|
161
169
|
SELECT pgflow.add_step(
|
|
@@ -169,6 +177,7 @@ SELECT pgflow.add_step(
|
|
|
169
177
|
#### Edge Cases and Special Behaviors
|
|
170
178
|
|
|
171
179
|
1. **Empty Array Cascade**: When a map step receives an empty array (`[]`):
|
|
180
|
+
|
|
172
181
|
- The SQL core completes it immediately without creating tasks
|
|
173
182
|
- The completed map step outputs an empty array
|
|
174
183
|
- Any dependent map steps also receive empty arrays and complete immediately
|
|
@@ -184,12 +193,14 @@ SELECT pgflow.add_step(
|
|
|
184
193
|
#### Implementation Details
|
|
185
194
|
|
|
186
195
|
Map steps utilize several database fields for state management:
|
|
196
|
+
|
|
187
197
|
- `initial_tasks`: Number of tasks to create (NULL until array size is known)
|
|
188
198
|
- `remaining_tasks`: Tracks incomplete tasks for the step
|
|
189
199
|
- `task_index`: Identifies which array element each task processes
|
|
190
200
|
- `step_type`: Column value 'map' triggers map behavior
|
|
191
201
|
|
|
192
202
|
The aggregation process ensures:
|
|
203
|
+
|
|
193
204
|
- **Order Preservation**: Task outputs maintain array element ordering
|
|
194
205
|
- **NULL Handling**: NULL outputs are included in the aggregated array
|
|
195
206
|
- **Atomicity**: Aggregation occurs within the same transaction as task completion
|
|
@@ -262,8 +273,9 @@ When a workflow starts:
|
|
|
262
273
|
The Edge Worker uses a two-phase approach to retrieve and start tasks:
|
|
263
274
|
|
|
264
275
|
**Phase 1 - Reserve Messages:**
|
|
276
|
+
|
|
265
277
|
```sql
|
|
266
|
-
SELECT * FROM
|
|
278
|
+
SELECT * FROM pgmq.read_with_poll(
|
|
267
279
|
queue_name => 'analyze_website',
|
|
268
280
|
vt => 60, -- visibility timeout in seconds
|
|
269
281
|
qty => 5 -- maximum number of messages to fetch
|
|
@@ -271,6 +283,7 @@ SELECT * FROM pgflow.read_with_poll(
|
|
|
271
283
|
```
|
|
272
284
|
|
|
273
285
|
**Phase 2 - Start Tasks:**
|
|
286
|
+
|
|
274
287
|
```sql
|
|
275
288
|
SELECT * FROM pgflow.start_tasks(
|
|
276
289
|
flow_slug => 'analyze_website',
|
|
@@ -379,6 +392,7 @@ Timeouts are enforced by setting the message visibility timeout to the step's ti
|
|
|
379
392
|
The SQL Core is the DAG orchestration engine that handles dependency resolution, step state management, and task spawning. However, workflows are defined using the TypeScript Flow DSL, which compiles user intent into the SQL primitives that populate the definition tables (`flows`, `steps`, `deps`).
|
|
380
393
|
|
|
381
394
|
See the [@pgflow/dsl package](../dsl/README.md) for complete documentation on:
|
|
395
|
+
|
|
382
396
|
- Expressing workflows with type-safe method chaining
|
|
383
397
|
- Step types (`.step()`, `.array()`, `.map()`)
|
|
384
398
|
- Compilation to SQL migrations
|
|
@@ -441,6 +455,7 @@ Map step tasks receive a fundamentally different input structure than single ste
|
|
|
441
455
|
```
|
|
442
456
|
|
|
443
457
|
This means:
|
|
458
|
+
|
|
444
459
|
- Map handlers process individual elements in isolation
|
|
445
460
|
- Map handlers cannot access the original flow input (`run`)
|
|
446
461
|
- Map handlers cannot access other dependencies
|
|
@@ -456,8 +471,10 @@ When a step depends on a map step, it receives the aggregated array output:
|
|
|
456
471
|
|
|
457
472
|
// A step depending on 'process_users' receives:
|
|
458
473
|
{
|
|
459
|
-
"run": {
|
|
460
|
-
|
|
474
|
+
"run": {
|
|
475
|
+
/* original flow input */
|
|
476
|
+
},
|
|
477
|
+
"process_users": [{ "name": "Alice" }, { "name": "Bob" }] // Full array
|
|
461
478
|
}
|
|
462
479
|
```
|
|
463
480
|
|
package/dist/CHANGELOG.md
CHANGED
|
@@ -1,29 +1,203 @@
|
|
|
1
1
|
# @pgflow/core
|
|
2
2
|
|
|
3
|
-
## 0.0.0-
|
|
3
|
+
## 0.0.0-condition-4354fcb6-20260108134756
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- c25ab9f: Add whenFailed option for error handling after retries exhausted (fail, skip, skip-cascade)
|
|
8
|
+
- 74202cd: Add skip infrastructure schema for conditional execution - new columns (condition_pattern, when_unmet, when_failed, skip_reason, skipped_at), 'skipped' status, and cascade_skip_steps function
|
|
9
|
+
- Updated dependencies [c25ab9f]
|
|
10
|
+
- @pgflow/dsl@0.0.0-condition-4354fcb6-20260108134756
|
|
11
|
+
|
|
12
|
+
## 0.13.1
|
|
13
|
+
|
|
14
|
+
### Patch Changes
|
|
15
|
+
|
|
16
|
+
- 199fbe1: Note: Version 0.13.0 was yanked due to broken local environment detection. This release (0.13.1) includes both the fix and the features from 0.13.0.
|
|
17
|
+
|
|
18
|
+
- Fix local environment detection to use SUPABASE_URL instead of API keys
|
|
19
|
+
- Add step output storage optimization for 2x faster Map chains (outputs now stored in step_states.output instead of aggregated on-demand)
|
|
20
|
+
- @pgflow/dsl@0.13.1
|
|
21
|
+
|
|
22
|
+
## 0.13.0
|
|
23
|
+
|
|
24
|
+
### Minor Changes
|
|
25
|
+
|
|
26
|
+
- 05738ed: Performance: Store step outputs atomically for 2x faster downstream task startup
|
|
27
|
+
|
|
28
|
+
Step outputs are now stored in step_states.output when steps complete, eliminating expensive aggregation queries. Benchmarks show 2.17x improvement for Map->Map chains. Includes data migration to backfill existing completed steps.
|
|
29
|
+
|
|
30
|
+
### Patch Changes
|
|
31
|
+
|
|
32
|
+
- @pgflow/dsl@0.13.0
|
|
33
|
+
|
|
34
|
+
## 0.12.0
|
|
35
|
+
|
|
36
|
+
### Minor Changes
|
|
37
|
+
|
|
38
|
+
- 37402eb: BREAKING: Asymmetric handler signatures - remove `run` key from step inputs
|
|
39
|
+
|
|
40
|
+
- Root steps: `(flowInput, ctx) => ...` - flow input directly as first param
|
|
41
|
+
- Dependent steps: `(deps, ctx) => ...` - only dependency outputs as first param
|
|
42
|
+
- Access flow input in dependent steps via `await ctx.flowInput` (async/lazy-loaded)
|
|
43
|
+
- Lazy loading prevents data duplication for map steps processing large arrays
|
|
44
|
+
- Enables functional composition and simplifies types for future subflows
|
|
45
|
+
|
|
46
|
+
### Patch Changes
|
|
47
|
+
|
|
48
|
+
- Updated dependencies [37402eb]
|
|
49
|
+
- Updated dependencies [5dc5cfc]
|
|
50
|
+
- @pgflow/dsl@0.12.0
|
|
51
|
+
|
|
52
|
+
## 0.11.0
|
|
53
|
+
|
|
54
|
+
### Minor Changes
|
|
55
|
+
|
|
56
|
+
- 0cb5500: New compilation config with allowDataLoss option for rapid iteration platforms. Breaking: ensureCompiledOnStartup removed in favor of compilation option.
|
|
57
|
+
|
|
58
|
+
### Patch Changes
|
|
59
|
+
|
|
60
|
+
- @pgflow/dsl@0.11.0
|
|
61
|
+
|
|
62
|
+
## 0.10.0
|
|
63
|
+
|
|
64
|
+
### Minor Changes
|
|
65
|
+
|
|
66
|
+
- 90276ce: Add automatic worker restart via `ensure_workers()` cron job that keeps edge functions running. Add `worker_functions` table for tracking registered edge functions and their health status. Add `stopped_at` column to workers table for graceful shutdown detection. Integrate `trackWorkerFunction` and `markWorkerStopped` into edge worker lifecycle for automatic registration and shutdown signaling.
|
|
67
|
+
|
|
68
|
+
### Patch Changes
|
|
69
|
+
|
|
70
|
+
- 0b84bb0: Add automatic flow compilation at worker startup. Workers now call ensure_flow_compiled to verify flows are up-to-date. In development, mismatched flows are recompiled automatically. In production, mismatches cause errors. Use ensureCompiledOnStartup: false to opt-out.
|
|
71
|
+
- Updated dependencies [0b84bb0]
|
|
72
|
+
- @pgflow/dsl@0.10.0
|
|
73
|
+
|
|
74
|
+
## 0.9.1
|
|
75
|
+
|
|
76
|
+
### Patch Changes
|
|
77
|
+
|
|
78
|
+
- Updated dependencies [992a86b]
|
|
79
|
+
- @pgflow/dsl@0.9.1
|
|
80
|
+
|
|
81
|
+
## 0.9.0
|
|
82
|
+
|
|
83
|
+
### Patch Changes
|
|
84
|
+
|
|
85
|
+
- @pgflow/dsl@0.9.0
|
|
86
|
+
|
|
87
|
+
## 0.8.1
|
|
88
|
+
|
|
89
|
+
### Patch Changes
|
|
90
|
+
|
|
91
|
+
- f1d3c32: Fix incorrect Supabase CLI version requirement from 2.34.3 to 2.50.3. CLI 2.50.3 is the first version to include pgmq 1.5.0+, which is required for pgflow 0.8.0+.
|
|
92
|
+
- @pgflow/dsl@0.8.1
|
|
93
|
+
|
|
94
|
+
## 0.8.0
|
|
95
|
+
|
|
96
|
+
### Minor Changes
|
|
97
|
+
|
|
98
|
+
- 7380237: BREAKING CHANGE: pgflow 0.8.0 requires pgmq 1.5.0+, PostgreSQL 17, and Supabase CLI 2.50.3+
|
|
99
|
+
|
|
100
|
+
This version modernizes infrastructure dependencies and will NOT work with pgmq 1.4.x or earlier. The migration includes a compatibility check that aborts with a clear error message if requirements are not met.
|
|
101
|
+
|
|
102
|
+
**Requirements:**
|
|
103
|
+
|
|
104
|
+
- pgmq 1.5.0 or higher (previously supported 1.4.x)
|
|
105
|
+
- PostgreSQL 17 (from 15)
|
|
106
|
+
- Supabase CLI 2.50.3 or higher (includes pgmq 1.5.0+)
|
|
107
|
+
|
|
108
|
+
**For Supabase users:** Upgrade your Supabase CLI to 2.50.3+ which includes pgmq 1.5.0 by default.
|
|
109
|
+
|
|
110
|
+
**For self-hosted users:** Upgrade pgmq to 1.5.0+ and PostgreSQL to 17 before upgrading pgflow.
|
|
111
|
+
|
|
112
|
+
**If you cannot upgrade immediately:** Stay on pgflow 0.7.x until your infrastructure is ready. The migration safety check ensures you cannot accidentally upgrade to an incompatible version.
|
|
113
|
+
|
|
114
|
+
### Patch Changes
|
|
115
|
+
|
|
116
|
+
- @pgflow/dsl@0.8.0
|
|
117
|
+
|
|
118
|
+
## 0.7.3
|
|
119
|
+
|
|
120
|
+
### Patch Changes
|
|
121
|
+
|
|
122
|
+
- @pgflow/dsl@0.7.3
|
|
123
|
+
|
|
124
|
+
## 0.7.2
|
|
125
|
+
|
|
126
|
+
### Patch Changes
|
|
127
|
+
|
|
128
|
+
- c22a1e5: Fix missing realtime broadcasts for step:started and step:completed events
|
|
129
|
+
|
|
130
|
+
**Critical bug fix:** Clients were not receiving `step:started` events when steps transitioned to Started status, and `step:completed` events for empty map steps and cascade completions were also missing.
|
|
131
|
+
|
|
132
|
+
**Root cause:** PostgreSQL query optimizer was eliminating CTEs containing `realtime.send()` calls because they were not referenced by subsequent operations or the final RETURN statement.
|
|
133
|
+
|
|
134
|
+
**Solution:** Moved `realtime.send()` calls directly into RETURNING clauses of UPDATE statements, ensuring they execute atomically with state changes and cannot be optimized away.
|
|
135
|
+
|
|
136
|
+
**Changes:**
|
|
137
|
+
|
|
138
|
+
- `start_ready_steps()`: Broadcasts step:started and step:completed events in RETURNING clauses
|
|
139
|
+
- `cascade_complete_taskless_steps()`: Broadcasts step:completed events atomically with cascade completion
|
|
140
|
+
- `complete_task()`: Added PERFORM statements for run:failed and step:failed broadcasts
|
|
141
|
+
- Client: Added `applySnapshot()` methods to FlowRun and FlowStep for proper initial state hydration without event emission
|
|
142
|
+
- @pgflow/dsl@0.7.2
|
|
143
|
+
|
|
144
|
+
## 0.7.1
|
|
145
|
+
|
|
146
|
+
### Patch Changes
|
|
147
|
+
|
|
148
|
+
- a71b371: Fix installation failures on new Supabase projects by removing pgmq version pin.
|
|
149
|
+
|
|
150
|
+
Supabase upgraded to pgmq 1.5.1 in Postgres 17.6.1.016+ (https://github.com/supabase/postgres/pull/1668), but pgflow was pinned to 1.4.4, causing "extension has no installation script" errors on fresh instances.
|
|
151
|
+
|
|
152
|
+
Only affects new projects - existing installations are unaffected and require no action.
|
|
153
|
+
|
|
154
|
+
Thanks to @kallebysantos for reporting this issue!
|
|
155
|
+
|
|
156
|
+
- @pgflow/dsl@0.7.1
|
|
157
|
+
|
|
158
|
+
## 0.7.0
|
|
4
159
|
|
|
5
160
|
### Minor Changes
|
|
6
161
|
|
|
7
162
|
- 524db03: Add map step type infrastructure in SQL core
|
|
8
163
|
|
|
9
|
-
|
|
164
|
+
⚠️ **This migration includes automatic data migration**
|
|
165
|
+
|
|
166
|
+
The migration will automatically update existing `step_states` rows to satisfy new constraints. This should complete without issues due to strict check constraints enforced in previous versions.
|
|
10
167
|
|
|
11
|
-
**
|
|
168
|
+
💡 **Recommended: Verify before deploying to production**
|
|
12
169
|
|
|
13
|
-
|
|
170
|
+
If you have existing production data and want to verify the migration will succeed cleanly, run this **read-only check query** (does not modify data) in **Supabase Studio** against your **production database**:
|
|
14
171
|
|
|
15
|
-
|
|
172
|
+
1. Open Supabase Studio → SQL Editor
|
|
173
|
+
2. Copy contents of `pkgs/core/queries/PRE_MIGRATION_CHECK_20251006073122.sql`
|
|
174
|
+
3. Execute against your production database (not local dev!)
|
|
175
|
+
4. Review results
|
|
16
176
|
|
|
17
|
-
|
|
177
|
+
**Expected output for successful migration:**
|
|
18
178
|
|
|
19
|
-
```sql
|
|
20
|
-
-- CRITICAL: Update existing step_states to satisfy new constraint
|
|
21
|
-
UPDATE pgflow.step_states
|
|
22
|
-
SET remaining_tasks = NULL
|
|
23
|
-
WHERE status = 'created';
|
|
24
179
|
```
|
|
180
|
+
type | identifier | details
|
|
181
|
+
---------------------------|---------------------------|------------------------------------------
|
|
182
|
+
DATA_BACKFILL_STARTED | run=def67890 step=process | initial_tasks will be set to 1 (...)
|
|
183
|
+
DATA_BACKFILL_COMPLETED | Found 100 completed steps | initial_tasks will be set to 1 (...)
|
|
184
|
+
INFO_SUMMARY | total_step_states=114 | created=0 started=1 completed=113 failed=0
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
**Interpretation:**
|
|
188
|
+
|
|
189
|
+
- ✅ Only `DATA_BACKFILL_*` and `INFO_SUMMARY` rows? **Safe to migrate**
|
|
190
|
+
- ⚠️ These are expected data migrations handled automatically by the migration
|
|
191
|
+
- 🆘 Unexpected rows or errors? Copy output and share on Discord for help
|
|
192
|
+
|
|
193
|
+
📝 **Note:** This check identifies data that needs migration but does not modify anything. Only useful for production databases with existing runs.
|
|
194
|
+
|
|
195
|
+
**Automatic data updates:**
|
|
196
|
+
|
|
197
|
+
- Sets `initial_tasks = 1` for all existing steps (correct for pre-map-step schema)
|
|
198
|
+
- Sets `remaining_tasks = NULL` for 'created' status steps (new semantics)
|
|
25
199
|
|
|
26
|
-
|
|
200
|
+
No manual intervention required.
|
|
27
201
|
|
|
28
202
|
***
|
|
29
203
|
|
|
@@ -66,7 +240,7 @@
|
|
|
66
240
|
|
|
67
241
|
- Updated dependencies [524db03]
|
|
68
242
|
- Updated dependencies [524db03]
|
|
69
|
-
- @pgflow/dsl@0.
|
|
243
|
+
- @pgflow/dsl@0.7.0
|
|
70
244
|
|
|
71
245
|
## 0.6.1
|
|
72
246
|
|
package/dist/PgflowSqlClient.js
CHANGED
|
@@ -9,7 +9,7 @@ export class PgflowSqlClient {
|
|
|
9
9
|
async readMessages(queueName, visibilityTimeout, batchSize, maxPollSeconds = 5, pollIntervalMs = 200) {
|
|
10
10
|
return await this.sql `
|
|
11
11
|
SELECT *
|
|
12
|
-
FROM
|
|
12
|
+
FROM pgmq.read_with_poll(
|
|
13
13
|
queue_name => ${queueName},
|
|
14
14
|
vt => ${visibilityTimeout},
|
|
15
15
|
qty => ${batchSize},
|
package/dist/README.md
CHANGED
|
@@ -5,10 +5,6 @@ PostgreSQL-native workflow engine for defining, managing, and tracking DAG-based
|
|
|
5
5
|
> [!NOTE]
|
|
6
6
|
> This project and all its components are licensed under [Apache 2.0](./LICENSE) license.
|
|
7
7
|
|
|
8
|
-
> [!WARNING]
|
|
9
|
-
> This project uses [Atlas](https://atlasgo.io/docs) to manage the schemas and migrations.
|
|
10
|
-
> See [ATLAS.md](ATLAS.md) for more details.
|
|
11
|
-
|
|
12
8
|
## Table of Contents
|
|
13
9
|
|
|
14
10
|
- [Overview](#overview)
|
|
@@ -47,6 +43,16 @@ This package focuses on:
|
|
|
47
43
|
|
|
48
44
|
The actual execution of workflow tasks is handled by the [Edge Worker](../edge-worker/README.md), which calls back to the SQL Core to acknowledge task completion or failure.
|
|
49
45
|
|
|
46
|
+
## Requirements
|
|
47
|
+
|
|
48
|
+
> [!IMPORTANT] > **pgmq Version Requirement** (since v0.8.0)
|
|
49
|
+
>
|
|
50
|
+
> pgflow v0.8.0 and later requires **pgmq 1.5.0 or higher**. This version of pgflow will NOT work with pgmq 1.4.x or earlier.
|
|
51
|
+
>
|
|
52
|
+
> - **Supabase Cloud**: Recent versions include pgmq 1.5.0+ by default
|
|
53
|
+
> - **Self-hosted**: You must upgrade pgmq to version 1.5.0+ before upgrading pgflow
|
|
54
|
+
> - **Version Check**: Run `SELECT extversion FROM pg_extension WHERE extname = 'pgmq';` to verify your pgmq version
|
|
55
|
+
|
|
50
56
|
## Key Features
|
|
51
57
|
|
|
52
58
|
- **Declarative Workflows**: Define flows and steps via SQL tables
|
|
@@ -140,6 +146,7 @@ SELECT pgflow.add_step(
|
|
|
140
146
|
#### Root Map vs Dependent Map
|
|
141
147
|
|
|
142
148
|
**Root Map Steps** process the flow's input array directly:
|
|
149
|
+
|
|
143
150
|
```sql
|
|
144
151
|
-- Root map: no dependencies, processes flow input
|
|
145
152
|
SELECT pgflow.add_step(
|
|
@@ -156,6 +163,7 @@ SELECT pgflow.start_flow(
|
|
|
156
163
|
```
|
|
157
164
|
|
|
158
165
|
**Dependent Map Steps** process another step's array output:
|
|
166
|
+
|
|
159
167
|
```sql
|
|
160
168
|
-- Dependent map: processes the array from 'fetch_items'
|
|
161
169
|
SELECT pgflow.add_step(
|
|
@@ -169,6 +177,7 @@ SELECT pgflow.add_step(
|
|
|
169
177
|
#### Edge Cases and Special Behaviors
|
|
170
178
|
|
|
171
179
|
1. **Empty Array Cascade**: When a map step receives an empty array (`[]`):
|
|
180
|
+
|
|
172
181
|
- The SQL core completes it immediately without creating tasks
|
|
173
182
|
- The completed map step outputs an empty array
|
|
174
183
|
- Any dependent map steps also receive empty arrays and complete immediately
|
|
@@ -184,12 +193,14 @@ SELECT pgflow.add_step(
|
|
|
184
193
|
#### Implementation Details
|
|
185
194
|
|
|
186
195
|
Map steps utilize several database fields for state management:
|
|
196
|
+
|
|
187
197
|
- `initial_tasks`: Number of tasks to create (NULL until array size is known)
|
|
188
198
|
- `remaining_tasks`: Tracks incomplete tasks for the step
|
|
189
199
|
- `task_index`: Identifies which array element each task processes
|
|
190
200
|
- `step_type`: Column value 'map' triggers map behavior
|
|
191
201
|
|
|
192
202
|
The aggregation process ensures:
|
|
203
|
+
|
|
193
204
|
- **Order Preservation**: Task outputs maintain array element ordering
|
|
194
205
|
- **NULL Handling**: NULL outputs are included in the aggregated array
|
|
195
206
|
- **Atomicity**: Aggregation occurs within the same transaction as task completion
|
|
@@ -262,8 +273,9 @@ When a workflow starts:
|
|
|
262
273
|
The Edge Worker uses a two-phase approach to retrieve and start tasks:
|
|
263
274
|
|
|
264
275
|
**Phase 1 - Reserve Messages:**
|
|
276
|
+
|
|
265
277
|
```sql
|
|
266
|
-
SELECT * FROM
|
|
278
|
+
SELECT * FROM pgmq.read_with_poll(
|
|
267
279
|
queue_name => 'analyze_website',
|
|
268
280
|
vt => 60, -- visibility timeout in seconds
|
|
269
281
|
qty => 5 -- maximum number of messages to fetch
|
|
@@ -271,6 +283,7 @@ SELECT * FROM pgflow.read_with_poll(
|
|
|
271
283
|
```
|
|
272
284
|
|
|
273
285
|
**Phase 2 - Start Tasks:**
|
|
286
|
+
|
|
274
287
|
```sql
|
|
275
288
|
SELECT * FROM pgflow.start_tasks(
|
|
276
289
|
flow_slug => 'analyze_website',
|
|
@@ -379,6 +392,7 @@ Timeouts are enforced by setting the message visibility timeout to the step's ti
|
|
|
379
392
|
The SQL Core is the DAG orchestration engine that handles dependency resolution, step state management, and task spawning. However, workflows are defined using the TypeScript Flow DSL, which compiles user intent into the SQL primitives that populate the definition tables (`flows`, `steps`, `deps`).
|
|
380
393
|
|
|
381
394
|
See the [@pgflow/dsl package](../dsl/README.md) for complete documentation on:
|
|
395
|
+
|
|
382
396
|
- Expressing workflows with type-safe method chaining
|
|
383
397
|
- Step types (`.step()`, `.array()`, `.map()`)
|
|
384
398
|
- Compilation to SQL migrations
|
|
@@ -441,6 +455,7 @@ Map step tasks receive a fundamentally different input structure than single ste
|
|
|
441
455
|
```
|
|
442
456
|
|
|
443
457
|
This means:
|
|
458
|
+
|
|
444
459
|
- Map handlers process individual elements in isolation
|
|
445
460
|
- Map handlers cannot access the original flow input (`run`)
|
|
446
461
|
- Map handlers cannot access other dependencies
|
|
@@ -456,8 +471,10 @@ When a step depends on a map step, it receives the aggregated array output:
|
|
|
456
471
|
|
|
457
472
|
// A step depending on 'process_users' receives:
|
|
458
473
|
{
|
|
459
|
-
"run": {
|
|
460
|
-
|
|
474
|
+
"run": {
|
|
475
|
+
/* original flow input */
|
|
476
|
+
},
|
|
477
|
+
"process_users": [{ "name": "Alice" }, { "name": "Bob" }] // Full array
|
|
461
478
|
}
|
|
462
479
|
```
|
|
463
480
|
|