:app is a per-kernel value; :principal is fixed at mint timeThe kernel needs two things from the host that it deliberately doesn't manage itself:
stube_sid cookie (so URL theft is harmless), but that's
ownership of the conversation, not authorisation of a person.Both could be implemented in user space — apps could stuff a
:db-pool reference on each conversation, or a :current-user map.
We've seen that go badly: the pool becomes stale across a deploy,
and the cached user keeps the page open after they've logged out
elsewhere.
Two embedder options on make-kernel:
:app — an opaque host value (typically a small map). Stored
on the kernel, not the conversation. Read from component code
via (s/app). Build it from JVM state at make-kernel time;
rebuild on every fresh kernel.:principal-fn — (fn [request] principal-or-nil). Called
exactly once when a conversation is minted. Result is stamped on
:conv/principal and surfaced via (s/principal). Fixed for
the life of the conversation. No set-principal! operation
exists; on login or logout, the host ends the conversation and
re-mints.make-kernel. A deploy or a
REPL reload picks them up fresh; persisted conversations
re-attach to whatever the new kernel has.(s/app) and (s/principal) are zero-arity. They read
dynamic vars the runtime binds during dispatch and render. Tests
that need a stand-in can rebind: (binding [dev.zeko.stube.kernel/*current-app* {:db stub}] …).set-principal!, the right move is (s/end nil) and a
redirect to the host's login route.:principal lands in EDN. The principal IS persisted with the
conversation, unlike :app. That's intentional — the principal
is a value (a user id, a role tuple), not a resource. If the
principal needs to be invalidated for security reasons (an account
was banned), the host either ends affected conversations or
filters them in its request pipeline.:app had to
be per-kernel, not per-conversationdocs/api.md — Application boundaries section under Embedding
in a host Ring app for the user-facing descriptionexamples/dev/zeko/stube/examples/protected_counter.clj — worked
exampleCan you improve this documentation?Edit on GitHub
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 |