persist: materialized views — stay current on write, O(1) read + 11 tests
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 27s
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 27s
view.sx: persist/view bundles stream + fold + snapshot name; view-attach subscribes it to a hub so each publish refreshes the snapshot incrementally, making view-peek an O(1) current read. view-value always folds the tail so it is never stale. The consumer read-model abstraction (feed indices, audit rollups, search counters). 122/122. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
49
lib/persist/view.sx
Normal file
49
lib/persist/view.sx
Normal file
@@ -0,0 +1,49 @@
|
||||
; persist/view — a materialized view: the consumer-facing read model. It bundles
|
||||
; a stream, a fold (step + seed) and a snapshot name. Attached to a hub it
|
||||
; refreshes incrementally on every publish, so the materialized value stays
|
||||
; current on write and reads are O(1) snapshot loads (persist/view-peek) instead
|
||||
; of a full fold. This is what feed indices, mod audit rollups, search counters,
|
||||
; etc. sit on. Requires: lib/persist/snapshot.sx, lib/persist/subscribe.sx.
|
||||
|
||||
(define persist/view (fn (name stream step seed) {:name name :step step :stream stream :seed seed}))
|
||||
(define persist/view-name (fn (v) (get v :name)))
|
||||
(define persist/view-stream (fn (v) (get v :stream)))
|
||||
|
||||
; bring the view's snapshot up to date with the log tail; returns the state
|
||||
(define
|
||||
persist/view-refresh
|
||||
(fn
|
||||
(b v)
|
||||
(persist/checkpoint
|
||||
b
|
||||
(get v :stream)
|
||||
(get v :name)
|
||||
(get v :step)
|
||||
(get v :seed))))
|
||||
|
||||
; current materialized value — refreshes first, so never stale
|
||||
(define
|
||||
persist/view-value
|
||||
(fn (b v) (persist/project-value (persist/view-refresh b v))))
|
||||
|
||||
; O(1) read of the last persisted snapshot value WITHOUT folding the tail. Equal
|
||||
; to view-value when the view is attached (kept current on every publish);
|
||||
; otherwise may lag the log by the un-refreshed tail.
|
||||
(define
|
||||
persist/view-peek
|
||||
(fn
|
||||
(b v)
|
||||
(persist/project-value
|
||||
(persist/snapshot-load b (get v :name) (get v :seed)))))
|
||||
|
||||
; attach to a hub: refresh the view on every publish to its stream
|
||||
(define
|
||||
persist/view-attach
|
||||
(fn
|
||||
(h v)
|
||||
(begin
|
||||
(persist/subscribe
|
||||
h
|
||||
(persist/view-stream v)
|
||||
(fn (bk s e) (persist/view-refresh bk v)))
|
||||
h)))
|
||||
Reference in New Issue
Block a user