You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Add idempotency key support for task deduplication
Two new fields on SpawnOptions:
- `only_once: bool` — auto-derives key from hash(task_name, params)
- `idempotency_key: Option<String>` — explicit key (takes precedence)
When a key is set, spawn_task checks for an existing non-terminal task
with the same key. If found, returns the existing task instead of
creating a duplicate. This enables first-served semantics where multiple
clients can safely try to spawn the same logical task.
DB changes:
- New nullable `idempotency_key` column on task tables
- Partial unique index on idempotency_key WHERE NOT NULL
- Migration adds column/index to all existing queues
- ensure_queue_tables updated for new queues
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
execute format('comment on column durable.%I.cancellation is %L', 't_'|| p_queue_name, '{"max_delay": <seconds>, "max_duration": <seconds>} - both optional. max_delay: cancel if not started within N seconds of enqueue. max_duration: cancel if not completed within N seconds of first start.');
118
+
execute format('comment on column durable.%I.idempotency_key is %L', 't_'|| p_queue_name, 'Optional dedup key. When set, only one non-terminal task with this key can exist. Set via SpawnOptions.only_once or SpawnOptions.idempotency_key.');
111
119
execute format('comment on column durable.%I.completed_payload is %L', 't_'|| p_queue_name, 'User-defined. Task return value. Schema depends on Task::Output type.');
112
120
113
121
execute format(
@@ -215,6 +223,13 @@ begin
215
223
't_'|| p_queue_name
216
224
);
217
225
226
+
-- Idempotency key unique index (partial: only non-null keys)
227
+
execute format(
228
+
'create unique index if not exists %I on durable.%I (idempotency_key) where idempotency_key is not null',
229
+
('t_'|| p_queue_name) ||'_ik',
230
+
't_'|| p_queue_name
231
+
);
232
+
218
233
-- Speed up claim timeout scans.
219
234
execute format(
220
235
'create index if not exists %I on durable.%I (claim_expires_at)
0 commit comments