persist: exactly-once append under retries + 9 tests
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 41s
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 41s
idempotency.sx: persist/append-once appends at most once per (stream, idempotency key), returning the same event on a repeat. The marker lives in the kv facet, so idempotency holds across a restart (verified on durable). persist/seen? check. 180/180. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
28
lib/persist/idempotency.sx
Normal file
28
lib/persist/idempotency.sx
Normal file
@@ -0,0 +1,28 @@
|
||||
; persist/idempotency — exactly-once append under retries. A command retried
|
||||
; after a network blip must not append its event twice. The caller supplies an
|
||||
; idempotency key; the first append for that (stream, key) stores the event and
|
||||
; remembers the key in the kv facet; a repeat returns the SAME event without
|
||||
; appending. Because the marker lives in kv, idempotency holds across a restart
|
||||
; too. Keyed per stream. Requires: lib/persist/log.sx, lib/persist/kv.sx.
|
||||
|
||||
(define persist/idem-key (fn (stream key) (str "idem/" stream "/" key)))
|
||||
|
||||
; true if an append-once has already been recorded for (stream, key)
|
||||
(define
|
||||
persist/seen?
|
||||
(fn (b stream key) (persist/kv-has? b (persist/idem-key stream key))))
|
||||
|
||||
; append at most once per (stream, key). Returns the stored event either way —
|
||||
; freshly appended on first use, the remembered one on a repeat.
|
||||
(define
|
||||
persist/append-once
|
||||
(fn
|
||||
(b stream key type at data)
|
||||
(let
|
||||
((k (persist/idem-key stream key)))
|
||||
(if
|
||||
(persist/kv-has? b k)
|
||||
(persist/kv-get b k)
|
||||
(let
|
||||
((ev (persist/append b stream type at data)))
|
||||
(begin (persist/kv-put b k ev) ev))))))
|
||||
Reference in New Issue
Block a user