Skip to content

Commit d1df2be

Browse files
committed
We have a tool to run a body only once, use it
`dosync` does not create an exclusion context on executing its body, so it's possible for two threads to enter the `dosync` and try to run `eval-fn` independently. Only one of them will win and get into `ref-map`, but there's still two outbound requests. This is bad. Delay actually promises exactly once execution and deferred execution, which are the two things we want. Makes sure that locks are localized on individual bodies and we don't e.g. lock on the entire map.
1 parent b47b131 commit d1df2be

File tree

1 file changed

+16
-12
lines changed

1 file changed

+16
-12
lines changed

Diff for: src/nodely/engine/lazy_env.clj

+16-12
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
(ns nodely.engine.lazy-env)
22

3-
(deftype LazySchedulingEnvironment [env ref-map eval-fn opts]
3+
(deftype LazySchedulingEnvironment [env delay-map opts]
44
clojure.lang.ILookup
55
(valAt [this k]
66
(or (.valAt this k nil)
@@ -10,23 +10,27 @@
1010
(throw ex))))
1111
(valAt [this k not-found]
1212
(if (find env k)
13-
(let [first-read @ref-map]
14-
(if (find first-read k)
15-
(get first-read k)
16-
(-> (dosync
17-
(let [second-read @ref-map]
18-
(if-not (find second-read k)
19-
(alter ref-map assoc k (eval-fn env k this opts))
20-
second-read)))
21-
(get k))))
13+
@(get delay-map k)
2214
not-found)))
2315

2416
(defn scheduled-nodes
2517
"Return the current map of nodes to applicative contexts in the
2618
LazySchedulingEnvironment `lazy-env`."
2719
[lazy-env]
28-
@(.-ref-map lazy-env))
20+
(reduce-kv (fn [m k v]
21+
(if (realized? v)
22+
(assoc m k @v)
23+
m))
24+
{}
25+
(.-delay-map lazy-env)))
2926

3027
(defn lazy-env
3128
[env eval-fn opts]
32-
(->LazySchedulingEnvironment env (ref {}) eval-fn opts))
29+
(let [this-promise (promise)
30+
delay-map (reduce-kv (fn [m k _]
31+
(assoc m k (delay (eval-fn env k @this-promise opts))))
32+
{}
33+
env)
34+
lookup (->LazySchedulingEnvironment env delay-map opts)]
35+
(deliver this-promise lookup)
36+
lookup))

0 commit comments

Comments
 (0)