Task implementation: state machine, executors, and the Task type.
Tasks progress through phases gated by CAS transitions on a MachineLatch.
See state-machine for the lifecycle definition and Task for coordination details.
Task implementation: state machine, executors, and the Task type. Tasks progress through phases gated by CAS transitions on a MachineLatch. See `state-machine` for the lifecycle definition and `Task` for coordination details.
The currently executing task, used for parent-child registration.
When a task's body executes, *this* is set in scope to that task. Any child
tasks created during execution register themselves with *this* for cascade
cancellation via WeakReference. This scope binding is set in -live-task's runner.
The currently executing task, used for parent-child registration. When a task's body executes, `*this*` is set in scope to that task. Any child tasks created during execution register themselves with `*this*` for cascade cancellation via `WeakReference`. This scope binding is set in `-live-task`'s runner.
(-pending-task executor)(-pending-task executor compelled)Create a new Task in pending state. The latch is used as the initial sentinel value in the state AtomicReference, allowing CAS to detect first write.
Create a new Task in pending state. The latch is used as the initial sentinel value in the state AtomicReference, allowing CAS to detect first write.
Transition to grounding. Entry point for grounding:
Transition to grounding. Entry point for grounding: - running → grounding (after executing function) - pending → grounding (direct value via doApply)
Transition settling → quiescent. Teardown complete.
Transition settling → quiescent. Teardown complete.
Transition pending → running. Task body begins execution.
Transition pending → running. Task body begins execution.
Transition writing → settling. Run settling subscriptions.
Transition writing → settling. Run settling subscriptions.
Transition grounding → transforming. Applies transform function to grounded value.
Transition grounding → transforming. Applies transform function to grounded value.
Transition to writing. Writes final result to state. Entry from:
Transition to writing. Writes final result to state. Entry from: - pending/running (cancellation or exception) - grounding (no transform) - transforming (after transform)
(do-applier executor v)(do-applier executor v e)(do-applier executor v e tf)Create a task that grounds a value (and optionally transforms it).
Unlike -live-task which runs a function, this applies a value directly.
The value is grounded (nested tasks resolved in parallel), then optionally
transformed by tf. Used by coordination functions like then, qmerge,
and qdo to await multiple values and apply a combining function.
Arities:
[executor v] - Ground v, no transform
[executor v e] - If e, fail with e; otherwise ground v
[executor v e tf] - If e, fail with e; otherwise ground v then apply tf
Create a task that grounds a value (and optionally transforms it). Unlike `-live-task` which runs a function, this applies a value directly. The value is grounded (nested tasks resolved in parallel), then optionally transformed by `tf`. Used by coordination functions like `then`, `qmerge`, and `qdo` to await multiple values and apply a combining function. Arities: `[executor v]` - Ground v, no transform `[executor v e]` - If e, fail with e; otherwise ground v `[executor v e tf]` - If e, fail with e; otherwise ground v then apply tf
(as-task this)Convert to a Task
Convert to a Task
(groundable? this)Should ground automatically resolve this?
Should ground automatically resolve this?
(taskable? this)Is this an async value that as-task handles specially?
Is this an async value that as-task handles specially?
Body done, resolving nested tasks (ground)
Body done, resolving nested tasks (ground)
Lifecycle complete. Parent has done its work; children may still be settling.
Quiescent means this task's lifecycle is finished, not that the entire subtree has stopped. Registered children received cancel signals (if alive and not compelled), orphaned tasks are unknown (may be GC'd or still running).
Lifecycle complete. Parent has done its work; children may still be settling. Quiescent means this task's lifecycle is finished, not that the entire subtree has stopped. Registered children received cancel signals (if alive and not compelled), orphaned tasks are unknown (may be GC'd or still running).
Result available, running then callbacks and cascade cancel.
When a task reaches settling:
We do NOT guarantee children are quiescent - only that they've started winding down. This is intentional: strong lifecycle coupling prevents GC, risks deadlocks, and doesn't match real-world async (you can't force a thread to stop immediately).
Result available, running `then` callbacks and cascade cancel. When a task reaches settling: - Its result is available (deref returns) - Grounded children are *at least* settling (we observed their settling) - Cascade cancellation is attempted on registered children (best effort) We do NOT guarantee children are quiescent - only that they've started winding down. This is intentional: strong lifecycle coupling prevents GC, risks deadlocks, and doesn't match real-world async (you can't force a thread to stop immediately).
Applying transform function to grounded value.
Applying transform function to grounded value.
Writing final result to task state. All completion paths converge here.
Writing final result to task state. All completion paths converge here.
(plain v)Wrap a value to indicate it contains no nested tasks and should skip grounding.
This is an optimization for combinators that produce values from already-resolved
task results (e.g., qmerge, qdo). The ground phase checks for Plain and
unwraps directly instead of walking the data structure.
Internal use only - not exposed in the public API.
Wrap a value to indicate it contains no nested tasks and should skip grounding. This is an optimization for combinators that produce values from already-resolved task results (e.g., `qmerge`, `qdo`). The `ground` phase checks for `Plain` and unwraps directly instead of walking the data structure. Internal use only - not exposed in the public API.
(plain? v)Returns true if v is wrapped in Plain, indicating it needs no grounding.
Returns true if v is wrapped in Plain, indicating it needs no grounding.
(submit executor f)Submit a callable to an executor. Returns a Future that can be used for cancellation.
Submit a callable to an executor. Returns a Future that can be used for cancellation.
(subscribe-callback task phase f)Attach a subscription to task, running f when reaching phase
f receives the current state of this as its only argument.
Attach a subscription to `task`, running `f` when reaching `phase` `f` receives the current state of `this` as its only argument.
(subscribe-cancel-future task phase fut-or-promise)Attach a subscription to task, cancelling the future (or promise
containing a future) fut-or-promise when the task reaches phase.
Attach a subscription to `task`, cancelling the future (or promise containing a future) `fut-or-promise` when the `task` reaches `phase`.
(subscribe-teardown task phase target)Attach a subscription to task, tearing down task target when reaching phase.
Attach a subscription to `task`, tearing down task `target` when reaching `phase`.
(subscribe-teardown-weak task phase target)Attach a subscription to task, tearing down task target when reaching phase.
Attach a subscription to `task`, tearing down task `target` when reaching `phase`.
(subscribe-unsub task phase target sub)Attach a subscription to task that removes sub from target when task enters phase.
Used for cleanup: when a child task settles, it removes its teardown subscription from the parent to prevent memory leaks in long-running parent tasks.
Attach a subscription to `task` that removes `sub` from `target` when `task` enters `phase`. Used for cleanup: when a child task settles, it removes its teardown subscription from the parent to prevent memory leaks in long-running parent tasks.
(throw-boxed-error state)Extract value from TaskState, throwing if exceptional.
Used by deref: if the task completed exceptionally, throws the boxed exception. Otherwise returns the result value.
Extract value from TaskState, throwing if exceptional. Used by deref: if the task completed exceptionally, throws the boxed exception. Otherwise returns the result value.
Virtual thread executor for IO-bound tasks. Creates a new virtual thread per task. Default executor for tasks - use for network calls, file IO, and blocking operations.
Virtual thread executor for IO-bound tasks. Creates a new virtual thread per task. Default executor for tasks - use for network calls, file IO, and blocking operations.
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 |