persist: optimistic concurrency — conflict as a real result + 8 tests
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Has been cancelled
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Has been cancelled
concurrency.sx: persist/append-expect refuses an append when the stream
advanced past the caller's expected seq, returning {:conflict :expected
:actual} instead of crashing or overwriting. persist/conflict? + accessors.
Phase 2 complete, 54/54.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
24
lib/persist/concurrency.sx
Normal file
24
lib/persist/concurrency.sx
Normal file
@@ -0,0 +1,24 @@
|
||||
; persist/concurrency — optimistic concurrency for the log facet. The caller
|
||||
; passes the seq it believes is current (the last-seq it last observed). If the
|
||||
; stream has advanced since, the append is refused and a conflict VALUE is
|
||||
; returned — never a crash, never a silent overwrite. The caller re-reads the
|
||||
; tail and retries. This is the substrate-level answer to "two writers, one
|
||||
; stream": the loser gets a result it can act on.
|
||||
; Requires: lib/persist/log.sx.
|
||||
|
||||
(define
|
||||
persist/append-expect
|
||||
(fn
|
||||
(b stream expected type at data)
|
||||
(let
|
||||
((actual (persist/last-seq b stream)))
|
||||
(if
|
||||
(= actual expected)
|
||||
(persist/append b stream type at data)
|
||||
{:actual actual :expected expected :conflict true}))))
|
||||
|
||||
(define
|
||||
persist/conflict?
|
||||
(fn (r) (if (has-key? r :conflict) (get r :conflict) false)))
|
||||
(define persist/conflict-expected (fn (r) (get r :expected)))
|
||||
(define persist/conflict-actual (fn (r) (get r :actual)))
|
||||
Reference in New Issue
Block a user