# Diff for migration 0011
**Migration file:** `0011_fix_cancellation_ordering.sql`
This diff was auto-generated by comparing schema state before and after applying migration 0011.
## Schema Diff
```diff
--- /var/folders/v5/0qbxlktj4nb4jzvgfg6jqljw0000gn/T/tmp.wGxSZE83jA 2026-01-30 21:32:28
+++ /var/folders/v5/0qbxlktj4nb4jzvgfg6jqljw0000gn/T/tmp.ghFPiJRC0E 2026-01-30 21:32:28
@@ -251,20 +251,19 @@
RAISE EXCEPTION 'Invalid lock token';
END IF;
- -- Step 2: Extract metadata from JSONB (including parent_instance_id)
+ -- Step 2: Extract metadata from JSONB
v_orchestration_name := p_metadata->>'orchestration_name';
v_orchestration_version := p_metadata->>'orchestration_version';
v_parent_instance_id := p_metadata->>'parent_instance_id';
v_status := p_metadata->>'status';
v_output := p_metadata->>'output';
- -- Step 3: Create or update instance metadata (including parent_instance_id)
+ -- Step 3: Create or update instance metadata
IF v_orchestration_name IS NOT NULL AND v_orchestration_version IS NOT NULL THEN
INSERT INTO SCHEMA.instances (instance_id, orchestration_name, orchestration_version, current_execution_id, parent_instance_id)
VALUES (v_instance_id, v_orchestration_name, v_orchestration_version, p_execution_id, v_parent_instance_id)
ON CONFLICT (instance_id) DO NOTHING;
- -- Update existing instance (but only set parent_instance_id if it was NULL)
UPDATE SCHEMA.instances i
SET orchestration_name = v_orchestration_name,
orchestration_version = v_orchestration_version,
@@ -304,20 +303,12 @@
UPDATE SCHEMA.executions e
SET status = v_status, output = v_output, completed_at = v_completed_at
WHERE e.instance_id = v_instance_id AND e.execution_id = p_execution_id;
- END IF;
-
- -- Step 8: Delete cancelled activities from worker_queue (lock stealing)
- -- This removes activities that were scheduled but not yet started/completed
- IF p_cancelled_activities IS NOT NULL AND JSONB_ARRAY_LENGTH(p_cancelled_activities) > 0 THEN
- FOR v_elem IN SELECT value FROM JSONB_ARRAY_ELEMENTS(p_cancelled_activities) LOOP
- DELETE FROM SCHEMA.worker_queue
- WHERE instance_id = v_elem->>'instance'
- AND execution_id = (v_elem->>'execution_id')::BIGINT
- AND activity_id = (v_elem->>'activity_id')::BIGINT;
- END LOOP;
END IF;
- -- Step 9: Enqueue worker items (batch) - now with activity identification
+ -- Step 8: Enqueue worker items FIRST - now with activity identification
+ -- IMPORTANT: This must happen BEFORE deleting cancelled activities so that
+ -- activities that are both scheduled AND cancelled in the same call get inserted
+ -- first, then deleted (supporting schedule-then-drop pattern)
IF p_worker_items IS NOT NULL AND JSONB_ARRAY_LENGTH(p_worker_items) > 0 THEN
FOR v_elem IN SELECT value FROM JSONB_ARRAY_ELEMENTS(p_worker_items) LOOP
-- Extract activity identification from ActivityExecute work item
@@ -333,6 +324,18 @@
INSERT INTO SCHEMA.worker_queue (work_item, visible_at, created_at, instance_id, execution_id, activity_id)
VALUES (v_elem::TEXT, v_now_ts, v_now_ts, v_item_instance_id, v_item_execution_id, v_item_activity_id);
+ END LOOP;
+ END IF;
+
+ -- Step 9: Delete cancelled activities from worker_queue (lock stealing)
+ -- IMPORTANT: This must happen AFTER inserting worker items so that activities
+ -- scheduled and cancelled in the same call are properly removed
+ IF p_cancelled_activities IS NOT NULL AND JSONB_ARRAY_LENGTH(p_cancelled_activities) > 0 THEN
+ FOR v_elem IN SELECT value FROM JSONB_ARRAY_ELEMENTS(p_cancelled_activities) LOOP
+ DELETE FROM SCHEMA.worker_queue
+ WHERE instance_id = v_elem->>'instance'
+ AND execution_id = (v_elem->>'execution_id')::BIGINT
+ AND activity_id = (v_elem->>'activity_id')::BIGINT;
END LOOP;
END IF;
```
---
*Generated on 2026-01-31 05:32:28 UTC*