Chez concurrency pt.3: async agents (per-agent serialized dispatch)
Replace the Janet synchronous agent shim (agent = atom, send applies inline) with JVM-style async agents: send/send-off enqueue an action and a single worker thread per agent applies them in order; deref reads the current (maybe not-yet-updated) state without blocking; await blocks until the queue drains. A validator rejection or a thrown action puts the agent in an error state (agent-error) and halts the queue; restart-agent clears it. send and send-off share one serialized worker (a superset of the JVM's fixed/cached pool split). Native versions re-asserted in post-prelude over the overlay; await/restart-agent are new. Corpus: the two "send/send-off applies" cases do (send a f) (deref a) with no await, so they now read state before the action runs — diverging like the JVM (the suite was literally "synchronous shim"). Allowlisted on both gates; floors -2 (zero-Janet 2569->2567, prelude 2559->2557). cli-test covers async agents via await (ordered 100-send dispatch, error capture) — 49/49. Janet gate + JVM cert green; 0 new divergences on either corpus. jolt-byjr
This commit is contained in:
parent
48ed72974f
commit
c719e54543
5 changed files with 120 additions and 7 deletions
|
|
@ -76,7 +76,14 @@
|
|||
["(require (quote [clojure.core.async :refer [chan go <! >! <!! alts!]])) (def x (chan)) (def y (chan)) (go (>! y :v)) (<!! (go (let [[v ch] (alts! [x y])] (and (= v :v) (= ch y)))))" "true"]
|
||||
["(require (quote [clojure.core.async :refer [chan go go-loop <! >! <!! close!]])) (def c (chan 10 (map inc))) (go (>! c 1) (>! c 2) (>! c 3) (close! c)) (<!! (go-loop [o []] (let [v (<! c)] (if (nil? v) o (recur (conj o v))))))" "[2 3 4]"]
|
||||
["(require (quote [clojure.core.async :refer [timeout <!!]])) (<!! (timeout 10)) :done" ":done"]
|
||||
["(require (quote [clojure.core.async :refer [chan go <! >! <!!]])) (def ^:dynamic *x* 0) (<!! (binding [*x* 7] (go (<! (clojure.core.async/timeout 5)) *x*)))" "7"]])
|
||||
["(require (quote [clojure.core.async :refer [chan go <! >! <!!]])) (def ^:dynamic *x* 0) (<!! (binding [*x* 7] (go (<! (clojure.core.async/timeout 5)) *x*)))" "7"]
|
||||
# jolt-byjr: async agents (serialized per-agent dispatch); await for determinism.
|
||||
["(deref (agent 0))" "0"]
|
||||
["(let [a (agent 0)] (send-off a + 5) (await a) (deref a))" "5"]
|
||||
["(let [a (agent 1)] (send a + 6) (await a) (deref a))" "7"]
|
||||
["(let [a (agent 0)] (dotimes [_ 100] (send a inc)) (await a) (deref a))" "100"]
|
||||
["(agent-error (agent 0))" ""]
|
||||
["(let [a (agent 0)] (send a (fn [_] (throw (ex-info \"boom\" {})))) (await a) (boolean (agent-error a)))" "true"]])
|
||||
|
||||
(each [src want] cases
|
||||
(def [code out err] (joltc src))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue