The reactive core: registry, invalidation, recomputation.
One engine wraps one backend connection. Writes go through exec! or transact!; the backend's preupdate hook materializes raw events into :pending on the writing thread (cheap swap!s only - the writer is never blocked); when the statement leaves the connection in autocommit mode a flush is scheduled off the writer. The flush resolves positional rows to column names (off-writer, as required
Scheduling is injectable; by default flushes go to a single background thread on the JVM and a microtask on JS, so watchers fire away from whichever thread wrote. Ordering within an engine is preserved: flushes drain until :pending is empty.
DDL (create/alter/drop through exec!) is not tracked by deps; it clears the column-name cache and re-derives every query's profile before the next recompute pass.
The registry maps id -> {:sql :params :deps :stmt :result :last}; :result is the deref-able, watchable atom returned by register!.
The reactive core: registry, invalidation, recomputation.
One engine wraps one backend connection. Writes go through exec!
or transact!; the backend's preupdate hook materializes raw events
into :pending on the writing thread (cheap swap!s only - the
writer is never blocked); when the statement leaves the connection
in autocommit mode a flush is scheduled off the writer. The flush
resolves positional rows to column names (off-writer, as required
- that needs a prepared statement), coalesces, matches against
registered deps, re-runs affected queries and resets only those
result atoms whose realized rows actually changed. sync! runs the
same flush synchronously for deterministic callers (tests).
Scheduling is injectable; by default flushes go to a single
background thread on the JVM and a microtask on JS, so watchers
fire away from whichever thread wrote. Ordering within an engine
is preserved: flushes drain until :pending is empty.
DDL (create/alter/drop through exec!) is not tracked by deps; it
clears the column-name cache and re-derives every query's profile
before the next recompute pass.
The registry maps id -> {:sql :params :deps :stmt :result :last};
:result is the deref-able, watchable atom returned by register!.(close! eng)Finalize every statement and close the backend. The engine is unusable afterwards.
Finalize every statement and close the backend. The engine is unusable afterwards.
(create b & {:keys [schedule]})Wire a backend into an engine: installs the event subscription and returns the engine (an atom). :schedule overrides flush dispatch (tests capture instead of run).
Wire a backend into an engine: installs the event subscription and returns the engine (an atom). :schedule overrides flush dispatch (tests capture instead of run).
(exec! eng sql)(exec! eng sql params)Run one statement through the backend and schedule a flush when it committed (autocommit). Exactly one statement.
Run one statement through the backend and schedule a flush when it committed (autocommit). Exactly one statement.
(flush! eng)Drain pending events: resolve names, coalesce, match, recompute affected queries, deliver changed results. Runs to completion (drains anything appended meanwhile). Throws when re-entered from a watcher - write via exec!, not by flushing recursively.
Drain pending events: resolve names, coalesce, match, recompute affected queries, deliver changed results. Runs to completion (drains anything appended meanwhile). Throws when re-entered from a watcher - write via exec!, not by flushing recursively.
(register! eng sql params)Compile and run a query once; returns its result atom (deref for rows, watch for changes, pass to unregister! when done). Deps are derived at registration via sqldeps over the backend's EQP tables.
Compile and run a query once; returns its result atom (deref for rows, watch for changes, pass to unregister! when done). Deps are derived at registration via sqldeps over the backend's EQP tables.
(sync! eng)Deterministic flush (see flush!). Takes the flush lock, so it waits out any in-flight scheduled flush rather than racing it.
Deterministic flush (see flush!). Takes the flush lock, so it waits out any in-flight scheduled flush rather than racing it.
(transact! eng stmts)Run statements as one transaction: [sql & params] vectors or bare sql strings. Flushes once after COMMIT; ROLLBACK on any failure (the rollback hook then discards pending events).
Run statements as one transaction: [sql & params] vectors or bare sql strings. Flushes once after COMMIT; ROLLBACK on any failure (the rollback hook then discards pending events).
(unregister! eng result)Retire a registered query's result atom: finalizes its statement. Atoms carry no metadata, so the entry is found by identity.
Retire a registered query's result atom: finalizes its statement. Atoms carry no metadata, so the entry is found by identity.
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 |