Repeating async work has two honest shapes, and one trap between
them. Parallel: qfor, one task per element. Sequential: plain
imperative code inside a single task — these are virtual threads,
so blocking is cheap and Thread/sleep in a loop is simply correct.
The trap is mixing the two: dotimes/doseq/run! spawning tasks
makes orphans — children never returned, cascade-cancelled the moment
the form settles, silently. __q/sleep itself is fine composed —
(qdo (__q/sleep 1000) (fire!)) is delay-then-do — the trap is
discarding what it returns. If you reached for dotimes around
__q/task or __q/sleep, reach for one of the shapes below instead.
Repeating async work has two honest shapes, and one trap between them. Parallel: `qfor`, one task per element. Sequential: plain imperative code *inside a single task* — these are virtual threads, so blocking is cheap and `Thread/sleep` in a loop is simply correct. The trap is mixing the two: `dotimes`/`doseq`/`run!` spawning tasks makes orphans — children never returned, cascade-cancelled the moment the form settles, silently. `__q/sleep` itself is fine *composed* — `(qdo (__q/sleep 1000) (fire!))` is delay-then-do — the trap is discarding what it returns. If you reached for `dotimes` around `__q/task` or `__q/sleep`, reach for one of the shapes below instead.
(sequentially f coll)Run f over coll one element at a time, inside one task: ordinary
imperative iteration, blocking allowed — a virtual thread makes
waiting cheap — settling to the vector of results in order. This is
the shape dotimes-spawning-tasks wanted to be: the iteration lives
inside the task, so nothing is orphaned and the eval's id addresses
the whole run.
Run `f` over `coll` one element at a time, inside one task: ordinary imperative iteration, blocking allowed — a virtual thread makes waiting cheap — settling to the vector of results in order. This is the shape `dotimes`-spawning-tasks wanted to be: the iteration lives *inside* the task, so nothing is orphaned and the eval's id addresses the whole run.
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 |