feat: core.async Phase 2 — dynamic var binding conveyance
Jolt's dynamic-var binding stack was a single global array, so concurrent go blocks interleaved each other's bindings and a go block didn't see the bindings in effect when it was spawned. Move the binding stack into Janet's fiber-local dyn (:jolt/binding-stack): each fiber (go block) lazily gets its own array, so bindings can't interleave. Janet ev/go fibers inherit the parent's dyn, but go-spawn now snapshots the binding stack at spawn time and installs a private copy in the new fiber — Clojure binding conveyance. A go block's own (binding ...) shadows the conveyed frame. types.janet: cur-binding-stack / snapshot-bindings / install-bindings; var-get/ var-set/push/pop use the fiber-local stack. async.janet: go-spawn conveys. spec: core.async/binding-conveyance (4 cases — conveyance, isolation, no leak to root, inner shadowing). jpm test green.
This commit is contained in:
parent
7d1e1f42e1
commit
e8cb4605ac
4 changed files with 52 additions and 9 deletions
|
|
@ -53,3 +53,19 @@
|
|||
"99" (a "(<! (go (try (<! (go 99)) (catch :default e -1))))")]
|
||||
["<! inside a nested fn called in a go"
|
||||
"7" (a "(def c (chan)) (go (>! c 7)) (<! (go ((fn [] (<! c)))))")])
|
||||
|
||||
# Dynamic-var binding conveyance (Phase 2): a go block sees the dynamic bindings
|
||||
# in effect when it was spawned, concurrent go blocks don't interleave, and a
|
||||
# go block's own binding shadows the conveyed one.
|
||||
(defn- d [body] (string "(do " REQ "(def ^:dynamic *x* 0) " body ")"))
|
||||
(defspec "core.async / binding conveyance"
|
||||
["go conveys the binding"
|
||||
"10" (d "(<! (binding [*x* 10] (go (<! (timeout 5)) *x*)))")]
|
||||
["concurrent go blocks isolated"
|
||||
"[:a :b]"
|
||||
(d "(def ra (binding [*x* :a] (go (<! (timeout 20)) *x*))) (def rb (binding [*x* :b] (go (<! (timeout 5)) *x*))) [(<! ra) (<! rb)]")]
|
||||
["binding doesn't leak to root"
|
||||
"0" (d "(<! (binding [*x* 99] (go (<! (timeout 5))))) *x*")]
|
||||
["go's own binding shadows conveyed"
|
||||
":inner"
|
||||
(d "(<! (binding [*x* :outer] (go (binding [*x* :inner] (<! (timeout 5)) *x*))))")])
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue