L1.5 · SqliteStore — the Phase-2 DURABLE SessionStore (02). Slots under the
SAME SessionStore port as MemoryStore with ZERO loop/kernel/adapter/api
changes; the only composition-root change is start-session! choosing it off
cfg :store. Mirrors MemoryStore's slot machinery (per-session :view/:lock/
:dispatch/:sci-ctx/:busy, the stamp-ids+ts counters, the live
delegation) and adds the durable layer:
• The canonical EVENT LOG + a minimal sessions table live in SQLite, PER SESSION,
keyed by (session_id, the monotonic event_id) — the future head event-range
boundary (02 §9). Raw JDBC, no wrapper dep.
• PAYLOADS live in a GLOBAL, file-based, content-addressed blob store
(blobstore) shared across sessions — no sid, content hash is globally
sufficient (02 §3).
⛔ PERSIST-BEFORE-FOLD (02 §8.2): under the per-session slot lock → stamp id+ts →
durably INSERT the event (committed) → ONLY on success swap! the in-process view
cache → schedule a NON-BLOCKING live notification. A failed persist throws BEFORE
the swap, so it never advances the view. create-session! reopens a persisted
session by FOLDING its durable log with the pure apply-event (deterministic
re-fold ⇒ the same ids, 02 §9) — the recovery path resume builds on.
L1.5 · SqliteStore — the Phase-2 DURABLE SessionStore (02). Slots under the SAME `SessionStore` port as MemoryStore with ZERO loop/kernel/adapter/api changes; the only composition-root change is `start-session!` choosing it off `cfg :store`. Mirrors MemoryStore's slot machinery (per-session `:view`/`:lock`/ `:dispatch`/`:sci-ctx`/`:busy`, the `stamp-ids+ts` counters, the `live` delegation) and adds the durable layer: • The canonical EVENT LOG + a minimal sessions table live in SQLite, PER SESSION, keyed by (`session_id`, the monotonic `event_id`) — the future head event-range boundary (02 §9). Raw JDBC, no wrapper dep. • PAYLOADS live in a GLOBAL, file-based, content-addressed blob store (`blobstore`) shared across sessions — no `sid`, content hash is globally sufficient (02 §3). ⛔ PERSIST-BEFORE-FOLD (02 §8.2): under the per-session slot lock → stamp id+ts → durably INSERT the event (committed) → ONLY on success swap! the in-process view cache → schedule a NON-BLOCKING live notification. A failed persist throws BEFORE the swap, so it never advances the view. `create-session!` reopens a persisted session by FOLDING its durable log with the pure `apply-event` (deterministic re-fold ⇒ the same ids, 02 §9) — the recovery path resume builds on.
(close! store)Release the store: stop every session's live dispatcher (idempotent; daemon
threads are JVM-exit-safe regardless) and close the JDBC connection. After this
a session can be durably reopened by constructing a fresh store on the same
dir (the recovery path) — this is what makes close+reopen behave like a
process restart in tests and resume.
Release the store: stop every session's live dispatcher (idempotent; daemon threads are JVM-exit-safe regardless) and close the JDBC connection. After this a session can be durably reopened by constructing a fresh store on the same `dir` (the recovery path) — this is what makes close+reopen behave like a process restart in tests and resume.
(sqlite-store {:keys [dir live-opts]})Open (creating if absent) a SqliteStore under dir: <dir>/events.db holds the
per-session event log + sessions table; <dir>/blobs/ is the GLOBAL blob store.
:live-opts ({:bound :drop}) seed each session's live dispatch. Multiple stores
may open the same dir (e.g. a process restart reopening for resume).
Open (creating if absent) a SqliteStore under `dir`: `<dir>/events.db` holds the
per-session event log + sessions table; `<dir>/blobs/` is the GLOBAL blob store.
`:live-opts` (`{:bound :drop}`) seed each session's live dispatch. Multiple stores
may open the same `dir` (e.g. a process restart reopening for resume).cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |