Concurrency gate — bounded-permit execution with timeout.
A gate wraps a java.util.concurrent.Semaphore with:
Three ways to use:
with-gate — bracket macro, throws on timeout (for call sites
that already have try/catch)
gate-run — function, returns Result (for railway-oriented pipelines)
deref-gate — gated deref for promises/futures with timeout
(replaces bare @ on blocking calls)
Usage: (def db-read (gate {:permits 4 :timeout-ms 15000 :name "db-read"})) (def db-write (gate {:permits 1 :timeout-ms 30000 :name "db-write"}))
;; Bracket — throws on timeout (with-gate db-read (query-database ...))
;; Result — returns err on timeout (gate-run db-write #(insert-record! ...))
;; Gated deref — replaces bare @ (deref-gate db-read (chroma/query coll embedding))
;; Diagnostics (gate-stats db-read) ;; => {:name "db-read" :permits 4 :available 3 :queued 1}
Concurrency gate — bounded-permit execution with timeout.
A gate wraps a java.util.concurrent.Semaphore with:
- Lifecycle management (start!/stop!)
- Timeout-aware permit acquisition
- Result integration (gate-run returns ok/err instead of throwing)
- Diagnostics (available permits, queue length)
Three ways to use:
1. `with-gate` — bracket macro, throws on timeout (for call sites
that already have try/catch)
2. `gate-run` — function, returns Result (for railway-oriented pipelines)
3. `deref-gate` — gated deref for promises/futures with timeout
(replaces bare @ on blocking calls)
Usage:
(def db-read (gate {:permits 4 :timeout-ms 15000 :name "db-read"}))
(def db-write (gate {:permits 1 :timeout-ms 30000 :name "db-write"}))
;; Bracket — throws on timeout
(with-gate db-read
(query-database ...))
;; Result — returns err on timeout
(gate-run db-write #(insert-record! ...))
;; Gated deref — replaces bare @
(deref-gate db-read (chroma/query coll embedding))
;; Diagnostics
(gate-stats db-read)
;; => {:name "db-read" :permits 4 :available 3 :queued 1}(deref-gate g derefable)(deref-gate g derefable timeout-ms)Deref a promise/future under the gate's permit with timeout.
Replaces bare @(chroma/query ...) with bounded concurrency + timeout.
Returns the deref'd value or throws on timeout/error.
Usage: (deref-gate read-gate (chroma/query coll embedding))
Deref a promise/future under the gate's permit with timeout. Replaces bare `@(chroma/query ...)` with bounded concurrency + timeout. Returns the deref'd value or throws on timeout/error. Usage: (deref-gate read-gate (chroma/query coll embedding))
(gate {:keys [permits timeout-ms name fair?]
:or {permits 1 timeout-ms 30000 name "gate" fair? true}})Create a concurrency gate.
Options: :permits — max concurrent executions (default 1, i.e. serialized) :timeout-ms — max wait for permit acquisition (default 30000) :name — diagnostic name (default "gate") :fair? — FIFO ordering for waiters (default true)
Returns a started Gate. No need to call start! separately.
Create a concurrency gate. Options: :permits — max concurrent executions (default 1, i.e. serialized) :timeout-ms — max wait for permit acquisition (default 30000) :name — diagnostic name (default "gate") :fair? — FIFO ordering for waiters (default true) Returns a started Gate. No need to call start! separately.
(gate-run g f)Execute f under the gate's permit. Returns Result.
On success: (ok <return-value>) On timeout: (err :gate/timeout {:name ... :timeout-ms ... :permits ...}) On error: (err :gate/execution-failed {:name ... :message ...})
Execute f under the gate's permit. Returns Result.
On success: (ok <return-value>)
On timeout: (err :gate/timeout {:name ... :timeout-ms ... :permits ...})
On error: (err :gate/execution-failed {:name ... :message ...})(gate-run! g f)Execute f under the gate's permit. Throws on timeout. For call sites that prefer exceptions over Result.
Execute f under the gate's permit. Throws on timeout. For call sites that prefer exceptions over Result.
(gate-stats g)Current gate state for diagnostics.
Returns: {:name "db-read" :permits 4 :available 3 :queue-length 1 :state :started}
Current gate state for diagnostics.
Returns:
{:name "db-read"
:permits 4
:available 3
:queue-length 1
:state :started}(with-gate g & body)Bracket macro — execute body under gate permit. Throws on timeout.
(with-gate db-read (query-database ...))
Bracket macro — execute body under gate permit. Throws on timeout. (with-gate db-read (query-database ...))
(with-gate-result g & body)Bracket macro — execute body under gate permit. Returns Result.
(with-gate-result db-write (insert-record! ...))
Bracket macro — execute body under gate permit. Returns Result. (with-gate-result db-write (insert-record! ...))
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 |