Liking cljdoc? Tell your friends :D

com.blockether.vis.internal.cancellation

Cancellation token - leaf module.

The cancellation token is a tiny two-atom record that lets a UI thread (TUI, REPL caller) cooperatively abort an in-flight turn! AND interrupt the worker future hosting the blocking provider call. The cooperative side is checked at every iteration boundary; the future side hard-cancels any HTTP call that has already started.

Public API:

(cancellation-token) - fresh token (cancellation-atom token) - cooperative flag atom (pass to turn!) (cancellation-set-future! token fut) - register the worker future (cancel! token) - set flag + interrupt registered future (cancel! token reason) - same, stamping WHO cancelled (cancel-reason token) - the recorded origin of the cancel (cancelled? token) - true once cancel! has been called (cancellation? throwable) - true if exception was caused by cancel! (preserve-interrupt! t) - re-arm the interrupt flag a catch-all ate

This namespace has zero side effects at load time and depends only on Java interop - channels and the runtime can require it directly without pulling in the rest of the SDK.

Cancellation token - leaf module.

The cancellation token is a tiny two-atom record that lets a UI
thread (TUI, REPL caller) cooperatively abort an
in-flight `turn!` AND interrupt the worker future hosting the
blocking provider call. The cooperative side is checked at every
iteration boundary; the future side hard-cancels any HTTP call
that has already started.

Public API:

  `(cancellation-token)`       - fresh token
  `(cancellation-atom token)`  - cooperative flag atom (pass to `turn!`)
  `(cancellation-set-future! token fut)` - register the worker future
  `(cancel! token)`            - set flag + interrupt registered future
  `(cancel! token reason)`     - same, stamping WHO cancelled
  `(cancel-reason token)`      - the recorded origin of the cancel
  `(cancelled? token)`         - true once `cancel!` has been called
  `(cancellation? throwable)`  - true if exception was caused by `cancel!`
  `(preserve-interrupt! t)`    - re-arm the interrupt flag a catch-all ate

This namespace has zero side effects at load time and depends only
on Java interop - channels and the runtime can require it
directly without pulling in the rest of the SDK.
raw docstring

cancel!clj

(cancel! token)
(cancel! token reason)

Abort the in-flight turn. Flips the cooperative flag and runs every registered on-cancel! callback exactly once. Each callback is wrapped in its own try/catch so one bad consumer cannot starve the rest.

The callback list is atomically drained before callbacks run. Repeated stops from a user, watchdog, or shutdown therefore preserve the first reason without re-entering a turn's terminal/unwind path.

reason names the ORIGIN (:client-cancel-turn, :stall-watchdog, :gateway-shutdown, …). The first one wins and is read back with cancel-reason. The one-arity call records :unspecified.

Abort the in-flight turn. Flips the cooperative flag and runs every registered
`on-cancel!` callback exactly once. Each callback is wrapped in its own
`try`/`catch` so one bad consumer cannot starve the rest.

The callback list is atomically drained before callbacks run. Repeated stops
from a user, watchdog, or shutdown therefore preserve the first reason without
re-entering a turn's terminal/unwind path.

`reason` names the ORIGIN (`:client-cancel-turn`, `:stall-watchdog`,
`:gateway-shutdown`, …). The first one wins and is read back with
[[cancel-reason]]. The one-arity call records `:unspecified`.
sourceraw docstring

cancel-reasonclj

(cancel-reason token)

Why this token was cancelled — the reason of the FIRST cancel! call, or nil when it was never cancelled (or came from a hand-built token).

Cancellation is the one turn outcome with no stack trace worth reading: the loop only sees an interrupt. Callers log this so a post mortem can tell a user stop from the daemon cancelling its own turn.

Why this token was cancelled — the `reason` of the FIRST `cancel!` call,
or nil when it was never cancelled (or came from a hand-built token).

Cancellation is the one turn outcome with no stack trace worth reading:
the loop only sees an interrupt. Callers log this so a post mortem can
tell a user stop from the daemon cancelling its own turn.
sourceraw docstring

cancellation-atomclj

(cancellation-atom token)

Cooperative flag atom — read with @ at iteration boundaries when the consumer can return without external help.

Cooperative flag atom — read with `@` at iteration boundaries when
the consumer can return without external help.
sourceraw docstring

cancellation-set-future!clj

(cancellation-set-future! token fut)

Register a worker Future so cancel! interrupts it. Thin convenience over on-cancel!: wraps .cancel(true) in a thunk and discards the returned dispose! (the future's own completion makes the second cancel a no-op).

Returns the future for convenient threading.

Register a worker `Future` so `cancel!` interrupts it. Thin
convenience over `on-cancel!`: wraps `.cancel(true)` in a thunk
and discards the returned `dispose!` (the future's own completion
makes the second cancel a no-op).

Returns the future for convenient threading.
sourceraw docstring

cancellation-tokenclj

(cancellation-token)

Construct a fresh cancellation token.

The token bundles three things every cancellable boundary needs:

  • ::flag — cooperative boolean atom, polled at iteration boundaries by callers that can return gracefully.
  • ::callbacks — vec of [id thunk] pairs run by cancel! so any number of in-flight workers (provider HTTP call, Python eval future, voice recorder) can register their own hard-cancel hook.
  • ::reason — WHO fired the cancel, stamped by cancel! and read back with cancel-reason. Downstream every cancel looks identical (a thread interrupt), so without this stamp a self-inflicted cancel (stall watchdog, shutdown) is indistinguishable from a user Esc.

cancellation-set-future! (legacy single-future API) is kept for call sites that have not migrated yet; it now routes through the callback registry too so behaviour stays identical.

Construct a fresh cancellation token.

The token bundles three things every cancellable boundary needs:
  - `::flag`      — cooperative boolean atom, polled at iteration
                     boundaries by callers that can return
                     gracefully.
  - `::callbacks` — vec of `[id thunk]` pairs run by `cancel!` so
                     any number of in-flight workers (provider
                     HTTP call, Python eval future, voice recorder)
                     can register their own hard-cancel hook.
  - `::reason`    — WHO fired the cancel, stamped by `cancel!` and read
                     back with `cancel-reason`. Downstream every cancel
                     looks identical (a thread interrupt), so without
                     this stamp a self-inflicted cancel (stall watchdog,
                     shutdown) is indistinguishable from a user Esc.

`cancellation-set-future!` (legacy single-future API) is kept for
call sites that have not migrated yet; it now routes through the
callback registry too so behaviour stays identical.
sourceraw docstring

cancellation?clj

(cancellation? e)

True if the given throwable was caused by a cancel! call. Channels should treat this as a normal (cancelled) outcome rather than an error and avoid showing stack traces.

True if the given throwable was caused by a `cancel!` call. Channels
should treat this as a normal (cancelled) outcome rather than an
error and avoid showing stack traces.
sourceraw docstring

cancelled?clj

(cancelled? token)

True once cancel! has been called on this token.

True once `cancel!` has been called on this token.
sourceraw docstring

on-cancel!clj

(on-cancel! token thunk)

Register a no-arg thunk to fire the moment cancel! is invoked on token. Returns a dispose! thunk the caller MUST invoke when the cancellable work finishes normally — otherwise callbacks accumulate for the token's lifetime.

If cancel! has already fired on this token, thunk runs synchronously here and dispose! is a no-op. This matches the contract every consumer wants: registering AFTER cancellation must still cancel, not silently swallow the request.

Replaces the atom-watch pattern earlier eval boundaries hand-rolled: one shared callback list, no per-consumer add-watch / remove-watch plumbing, no risk of leaving a watch on the flag after the worker finishes.

Register a no-arg `thunk` to fire the moment `cancel!` is invoked
on `token`. Returns a `dispose!` thunk the caller MUST invoke when
the cancellable work finishes normally — otherwise callbacks
accumulate for the token's lifetime.

If `cancel!` has already fired on this token, `thunk` runs
synchronously here and `dispose!` is a no-op. This matches the
contract every consumer wants: registering AFTER cancellation
must still cancel, not silently swallow the request.

Replaces the atom-watch pattern earlier eval boundaries hand-rolled:
one shared callback list, no per-consumer add-watch / remove-watch
plumbing, no risk of leaving a watch on the flag after the worker
finishes.
sourceraw docstring

preserve-interrupt!clj

(preserve-interrupt! t)

Re-arm THIS thread's interrupt flag when t is, or wraps, an InterruptedException, and answer whether it did.

The JVM CLEARS the flag as it throws, so a best-effort (catch Throwable _ ...) around anything that BLOCKS -- .waitFor on a subprocess, Thread/sleep, an unbounded deref -- silently EATS the cancellation: cancel! interrupted the turn, the handler answered its fallback value, and the thread polled on to its own deadline as if nothing had happened. Every catch-all that can see a blocking call runs this FIRST: the fallback value still stands (the measurement, the git output, the token really is unavailable), while the cancellation survives to the next interruptible call, which throws at once.

CancellationException is deliberately NOT re-armed -- some OTHER future was cancelled; this thread was never interrupted, and pretending otherwise would abort work nobody asked to stop.

Re-arm THIS thread's interrupt flag when `t` is, or wraps, an
`InterruptedException`, and answer whether it did.

The JVM CLEARS the flag as it throws, so a best-effort
`(catch Throwable _ ...)` around anything that BLOCKS -- `.waitFor` on a
subprocess, `Thread/sleep`, an unbounded `deref` -- silently EATS the
cancellation: [[cancel!]] interrupted the turn, the handler answered its
fallback value, and the thread polled on to its own deadline as if nothing
had happened. Every catch-all that can see a blocking call runs this FIRST:
the fallback value still stands (the measurement, the git output, the token
really is unavailable), while the cancellation survives to the next
interruptible call, which throws at once.

`CancellationException` is deliberately NOT re-armed -- some OTHER future was
cancelled; this thread was never interrupted, and pretending otherwise would
abort work nobody asked to stop.
sourceraw docstring

virtual-threads-available?clj

(virtual-threads-available?)

True when this JVM exposes Java virtual-thread APIs. Reflection keeps source compatible with older runtimes.

True when this JVM exposes Java virtual-thread APIs. Reflection keeps
source compatible with older runtimes.
sourceraw docstring

worker-futureclj

(worker-future f)
(worker-future name f)
(worker-future name f {:keys [platform?]})

Run f on a cancellable worker Future. Uses a virtual thread when the JVM supports it, otherwise falls back to a named daemon platform thread.

Pass {:platform? true} for work that can pin a virtual-thread carrier in native or uninterruptible code. A platform worker costs one thread but cannot starve the virtual-thread scheduler that runs ordinary lightweight work.

The returned value implements java.util.concurrent.Future plus Clojure deref/realized? protocols so legacy future call sites can migrate without losing timeout/cancellation behavior.

Run `f` on a cancellable worker Future. Uses a virtual thread when the JVM
supports it, otherwise falls back to a named daemon platform thread.

Pass `{:platform? true}` for work that can pin a virtual-thread carrier in
native or uninterruptible code. A platform worker costs one thread but cannot
starve the virtual-thread scheduler that runs ordinary lightweight work.

The returned value implements java.util.concurrent.Future plus Clojure
deref/realized? protocols so legacy `future` call sites can migrate without
losing timeout/cancellation behavior.
sourceraw docstring

worker-runtimeclj

(worker-runtime)

Runtime probe for worker execution. :worker-helper is stable metadata for diagnostics; :virtual-threads? reports whether new worker tasks will use Java virtual threads.

Runtime probe for worker execution. `:worker-helper` is stable metadata for
diagnostics; `:virtual-threads?` reports whether new worker tasks will use
Java virtual threads.
sourceraw docstring

cljdoc builds & hosts documentation for Clojure/Script libraries

Keyboard shortcuts
Ctrl+kJump to recent docs
Move to previous article
Move to next article
Ctrl+/Jump to the search field
× close