Skip to content

Commit 045f557

Browse files
committed
fix(cascade): add safety limit to prevent infinite loops during taskless step completion
- Implemented a maximum iteration count of 50 in the cascade_complete_taskless_steps function - Added a safety counter to avoid potential infinite loops in cascade processing - Updated loop logic to raise an exception if safety limit is exceeded - Minor formatting adjustments for clarity and consistency
1 parent 05e2388 commit 045f557

File tree

1 file changed

+14
-5
lines changed

1 file changed

+14
-5
lines changed

PLAN_cascade_complete_taskless_steps.md

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ This reduces cascade calls from 10,000 (every task) to 1 (when step completes)!
105105

106106
### The Cascade Function
107107

108-
Use a simple loop that completes all ready taskless steps:
108+
Use a simple loop that completes all ready taskless steps with safety measures:
109109

110110
```sql
111111
CREATE OR REPLACE FUNCTION pgflow.cascade_complete_taskless_steps(run_id uuid)
@@ -115,8 +115,16 @@ AS $$
115115
DECLARE
116116
v_total_completed int := 0;
117117
v_iteration_completed int;
118+
v_iterations int := 0;
119+
v_max_iterations int := 50; -- Safety limit matching worst-case analysis
118120
BEGIN
119121
LOOP
122+
-- Safety counter to prevent infinite loops
123+
v_iterations := v_iterations + 1;
124+
IF v_iterations > v_max_iterations THEN
125+
RAISE EXCEPTION 'Cascade loop exceeded safety limit of % iterations', v_max_iterations;
126+
END IF;
127+
120128
WITH completed AS (
121129
UPDATE pgflow.step_states
122130
SET status = 'completed',
@@ -133,24 +141,25 @@ BEGIN
133141
UPDATE pgflow.step_states ss
134142
SET remaining_deps = ss.remaining_deps - 1
135143
FROM completed c
136-
JOIN pgflow.deps d ON d.flow_slug = c.flow_slug
144+
JOIN pgflow.deps d ON d.flow_slug = c.flow_slug
137145
AND d.dep_slug = c.step_slug
138-
WHERE ss.run_id = c.run_id
146+
WHERE ss.run_id = c.run_id
139147
AND ss.step_slug = d.step_slug
140148
),
141149
-- Send realtime events and update run count...
142150
SELECT COUNT(*) INTO v_iteration_completed FROM completed;
143-
151+
144152
EXIT WHEN v_iteration_completed = 0;
145153
v_total_completed := v_total_completed + v_iteration_completed;
146154
END LOOP;
147-
155+
148156
RETURN v_total_completed;
149157
END;
150158
$$;
151159
```
152160

153161
**Performance**: 50 iterations once per step completion is acceptable
162+
**Safety**: Hard iteration limit prevents infinite loops from logic errors
154163

155164
### Integration Points
156165

0 commit comments

Comments
 (0)