Resource lifecycle macros for bracket-pattern and scoped cleanup.
Provides two complementary patterns:
with-resource — Single resource bracket pattern.
Acquire returns Result; release ALWAYS runs in finally.
with-scope / scope-acquire! — Multi-resource LIFO cleanup.
Resources released in reverse acquisition order on scope exit.
Both compose naturally with let-ok and the Result monad.
Resource lifecycle macros for bracket-pattern and scoped cleanup. Provides two complementary patterns: 1. `with-resource` — Single resource bracket pattern. Acquire returns Result; release ALWAYS runs in finally. 2. `with-scope` / `scope-acquire!` — Multi-resource LIFO cleanup. Resources released in reverse acquisition order on scope exit. Both compose naturally with `let-ok` and the Result monad.
(new-scope)Create a new resource scope. Returns an atom holding a stack of [resource cleanup-fn] pairs.
Create a new resource scope. Returns an atom holding a stack of [resource cleanup-fn] pairs.
(scope-acquire! scope acquire-fn args)(scope-acquire! scope cleanup-fn acquire-fn args)Acquire a resource within a scope. Applies acquire-fn to args (a vector), which must return a Result. On ok, pushes [resource cleanup-fn] onto the scope stack and returns the Result. On err, returns the error. cleanup-fn defaults to identity.
Usage: (scope-acquire! scope open-db [config]) (scope-acquire! scope close-db! open-db [config])
Acquire a resource within a scope. Applies acquire-fn to args (a vector), which must return a Result. On ok, pushes [resource cleanup-fn] onto the scope stack and returns the Result. On err, returns the error. cleanup-fn defaults to identity. Usage: (scope-acquire! scope open-db [config]) (scope-acquire! scope close-db! open-db [config])
(scope-release! scope)Release all resources in a scope in LIFO order. Errors during cleanup are collected but do not stop the sweep. Returns vector of any cleanup errors (empty on success).
Release all resources in a scope in LIFO order. Errors during cleanup are collected but do not stop the sweep. Returns vector of any cleanup errors (empty on success).
(with-resource [sym acquire-expr] & body)Bracket pattern: acquire resource, use it, always release.
Acquire-expr must return a Result. On ok, binds the value to sym and executes body. On err, short-circuits. Release fn ALWAYS runs in finally (even on exception). Release errors are swallowed.
Usage: (with-resource [conn (acquire-db config)] :release close-db! (let-ok [data (query conn "...")] (ok (process data))))
Expansion: (let [acquired (acquire-db config)] (if (ok? acquired) (let [conn (:ok acquired)] (try (let-ok [data (query conn "...")] (ok (process data))) (finally (try (close-db! conn) (catch Throwable _))))) acquired))
Bracket pattern: acquire resource, use it, always release.
Acquire-expr must return a Result. On ok, binds the value to sym
and executes body. On err, short-circuits. Release fn ALWAYS runs
in finally (even on exception). Release errors are swallowed.
Usage:
(with-resource [conn (acquire-db config)]
:release close-db!
(let-ok [data (query conn "...")]
(ok (process data))))
Expansion:
(let [acquired (acquire-db config)]
(if (ok? acquired)
(let [conn (:ok acquired)]
(try
(let-ok [data (query conn "...")]
(ok (process data)))
(finally
(try (close-db! conn) (catch Throwable _)))))
acquired))(with-scope [scope-sym] & body)Multi-resource scope with LIFO cleanup on exit.
Usage: (with-scope [scope] (let-ok [db (scope-acquire! scope close-db! open-db [config]) conn (scope-acquire! scope close-nrepl! open-nrepl [port])] (ok (process db conn)))) ;; conn released first, then db (LIFO)
Multi-resource scope with LIFO cleanup on exit.
Usage:
(with-scope [scope]
(let-ok [db (scope-acquire! scope close-db! open-db [config])
conn (scope-acquire! scope close-nrepl! open-nrepl [port])]
(ok (process db conn))))
;; conn released first, then db (LIFO)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 |