Effectful boundary of the addon mounter — all IO and var resolution, injected through the IMountHost port and an optional config resolver.
Collect: discover-specs scans the classpath for META-INF/hive-addons/*.edn. Promote: parse-spec turns an EDN string into a validated MountSpec Result. Pipeline is hive-addon.mount.solve (pure, elsewhere). Boundary: mount!/dry-run/teardown! resolve constructors, inject already-mounted sibling instances into each dependent's config (DIP), and drive the host.
mount! GRACEFULLY DEGRADES: a spec that fails at any step is recorded in the MountReport and the loop CONTINUES; already-mounted addons are NEVER torn down on a mid-DAG failure. teardown! shuts down in reverse mount order and always reports :teardown/data-preserved? true (shutdown! never deletes data).
Effectful boundary of the addon mounter — all IO and var resolution, injected through the IMountHost port and an optional config resolver. Collect: discover-specs scans the classpath for META-INF/hive-addons/*.edn. Promote: parse-spec turns an EDN string into a validated MountSpec Result. Pipeline is hive-addon.mount.solve (pure, elsewhere). Boundary: mount!/dry-run/teardown! resolve constructors, inject already-mounted sibling instances into each dependent's config (DIP), and drive the host. mount! GRACEFULLY DEGRADES: a spec that fails at any step is recorded in the MountReport and the loop CONTINUES; already-mounted addons are NEVER torn down on a mid-DAG failure. teardown! shuts down in reverse mount order and always reports :teardown/data-preserved? true (shutdown! never deletes data).
Default bounded initializer retry policy. :max-attempts counts the first call.
Default bounded initializer retry policy. :max-attempts counts the first call.
(discover-specs)(discover-specs classloader)Scan the classpath for META-INF/hive-addons/*.edn and parse each into a MountSpec. Returns {:specs [MountSpec] :errors [{:url .. :errors ..}]}. Result-guarded: a bad file becomes an :errors entry, never aborts the scan.
Scan the classpath for META-INF/hive-addons/*.edn and parse each into a
MountSpec. Returns {:specs [MountSpec] :errors [{:url .. :errors ..}]}.
Result-guarded: a bad file becomes an :errors entry, never aborts the scan.(dry-run plan host)(dry-run plan _host {:keys [license-gate]})Compute the MountReport that mounting would produce WITHOUT any effects: no construction, registration, or initialization. Applies the licence gate and resolves each ctor read-only, marking a spec :phase :skipped :success? true when it would mount, :phase :entitlement when the gate refuses, else :phase :resolved :success? false. Golden-replay parity: for an all-success plan, dry-run :order and :mounted ids equal mount! :order and :mounted ids.
Compute the MountReport that mounting would produce WITHOUT any effects: no construction, registration, or initialization. Applies the licence gate and resolves each ctor read-only, marking a spec :phase :skipped :success? true when it would mount, :phase :entitlement when the gate refuses, else :phase :resolved :success? false. Golden-replay parity: for an all-success plan, dry-run :order and :mounted ids equal mount! :order and :mounted ids.
(mount! plan host)(mount! plan
host
{:keys [resolve-config init-retry on-event sleep-fn license-gate
peer-specs]
:or {resolve-config port/resolve-config-default
init-retry {}
on-event (constantly nil)
sleep-fn (fn [ms] (Thread/sleep (long ms)))}})Mount every spec in (plan :ordered) into host, in order. Returns a MountReport. For each spec: check the licence gate, resolve ctor, build config via resolve-config then inject already-mounted sibling instances under :mount/dependencies, construct, verify IAddon, register!, init!. Any failure is recorded and the loop CONTINUES — already-mounted addons are NEVER torn down (graceful degrade). :ok? is true only when every attempted spec succeeded.
opts: {:resolve-config (fn [spec] -> config-map) (default resolve-config-default) :init-retry retry-policy override :license-gate ILicenseGate or (fn [spec] -> nil | reason) (default: the installed gate) :peer-specs the spec set used to resolve each spec's dependencies for sibling injection (default: the plan's own :ordered) :on-event (fn [event-map]) :sleep-fn (fn [milliseconds])}.
:peer-specs exists for mounting a SLICE of a larger system — a hot-reload remounts only the affected addons, but their capability-providing siblings live outside that slice. Resolving dependencies against :ordered alone would silently drop those siblings from :mount/dependencies, handing the remounted addon a thinner config than its original mount got.
Mount every spec in (plan :ordered) into host, in order. Returns a MountReport.
For each spec: check the licence gate, resolve ctor, build config via
resolve-config then inject already-mounted sibling instances under
:mount/dependencies, construct, verify IAddon, register!, init!. Any failure
is recorded and the loop CONTINUES — already-mounted addons are NEVER torn
down (graceful degrade). :ok? is true only when every attempted spec
succeeded.
opts: {:resolve-config (fn [spec] -> config-map) (default resolve-config-default)
:init-retry retry-policy override
:license-gate ILicenseGate or (fn [spec] -> nil | reason)
(default: the installed gate)
:peer-specs the spec set used to resolve each spec's dependencies
for sibling injection (default: the plan's own :ordered)
:on-event (fn [event-map])
:sleep-fn (fn [milliseconds])}.
:peer-specs exists for mounting a SLICE of a larger system — a hot-reload
remounts only the affected addons, but their capability-providing siblings
live outside that slice. Resolving dependencies against :ordered alone would
silently drop those siblings from :mount/dependencies, handing the remounted
addon a thinner config than its original mount got.(parse-spec edn-string)Parse an EDN manifest string into a validated MountSpec. (r/ok MountSpec) on success; (r/err :mount/spec-invalid {:explanation ..}) on a read error or schema violation.
Parse an EDN manifest string into a validated MountSpec.
(r/ok MountSpec) on success; (r/err :mount/spec-invalid {:explanation ..})
on a read error or schema violation.(resolve-constructor spec)Resolve a MountSpec constructor without erasing load failures.
Returns tagged resolution data. :absent means no such var; :failed
means requiring the constructor namespace threw (including compiler/load
order failures); :invalid means the var exists but is not callable.
Never throws ordinary Exceptions.
Resolve a MountSpec constructor without erasing load failures. Returns tagged resolution data. `:absent` means no such var; `:failed` means requiring the constructor namespace threw (including compiler/load order failures); `:invalid` means the var exists but is not callable. Never throws ordinary Exceptions.
(teardown! host addon-ids)Shut down addon-ids in REVERSE order via (port/shutdown! host id). Returns a TeardownReport. :teardown/data-preserved? is always true (shutdown! never deletes data); a shutdown that throws is recorded in :errors but the flag stays true — we did not delete.
Shut down addon-ids in REVERSE order via (port/shutdown! host id). Returns a TeardownReport. :teardown/data-preserved? is always true (shutdown! never deletes data); a shutdown that throws is recorded in :errors but the flag stays true — we did not delete.
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 |