Skip to content

Commit 2dbf783

Browse files
committed
next-id (#20)
1 parent 418d7ca commit 2dbf783

File tree

2 files changed

+139
-112
lines changed

2 files changed

+139
-112
lines changed

src/darkleaf/di/core.clj

Lines changed: 125 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,9 @@
4343
(defn- seq-contains? [xs x]
4444
(not (neg? (index-of xs x))))
4545

46+
(defn ^:dynamic *next-id* []
47+
(throw (IllegalStateException. "Attempting to call unbound `di/*next-id*`")))
48+
4649
(def ^:private dependency-type-priority
4750
{:required 1
4851
:optional 2})
@@ -120,8 +123,9 @@
120123
built-map))
121124

122125
:else
123-
(let [obj (build-obj built-map factory)]
124-
(vswap! *stop-list conj #(p/demolish factory obj))
126+
(let [obj (build-obj built-map factory)
127+
stop (bound-fn* #(p/demolish factory obj))]
128+
(vswap! *stop-list conj stop)
125129
(case [obj dep-type]
126130
[nil :optional] (recur tail built-map)
127131
[nil :required] (missing-dependency! stack)
@@ -205,6 +209,11 @@
205209
(map? key) [::implicit-root {::implicit-root (-> key (update-vals ref) template)}]
206210
true [key nil]))
207211

212+
(defn- ->next-id []
213+
(let [id (atom -1)]
214+
(fn next-id []
215+
(swap! id inc))))
216+
208217
(defn ^AutoCloseable start
209218
"Starts a system of dependent objects.
210219
@@ -255,86 +264,90 @@
255264
See the tests for use cases.
256265
See `update-key`."
257266
[key & middlewares]
258-
(let [[key root-registry] (key->key&registry key)
259-
260-
middlewares (concat [with-env with-ns root-registry] middlewares)
261-
registry (apply-middleware nil-registry middlewares)
262-
ctx {:registry registry
263-
:*stop-list (volatile! '())}
264-
obj (try-build ctx key)]
265-
^{:type ::root
266-
::print obj}
267-
(reify
268-
AutoCloseable
269-
(close [_]
270-
(->> (try-stop-started ctx)
271-
(throw-many!)))
272-
IDeref
273-
(deref [_]
274-
obj)
275-
Indexed
276-
(nth [_ i]
277-
(nth obj i))
278-
(nth [_ i not-found]
279-
(nth obj i not-found))
280-
(count [_]
281-
(count obj))
282-
ILookup
283-
(valAt [_ key]
284-
(get obj key))
285-
(valAt [_ key not-found]
286-
(get obj key not-found))
287-
IFn
288-
(call [_]
289-
(.call ^IFn obj))
290-
(run [_]
291-
(.run ^IFn obj))
292-
(invoke [this]
293-
(.invoke ^IFn obj))
294-
(invoke [_ a1]
295-
(.invoke ^IFn obj a1))
296-
(invoke [_ a1 a2]
297-
(.invoke ^IFn obj a1 a2))
298-
(invoke [_ a1 a2 a3]
299-
(.invoke ^IFn obj a1 a2 a3))
300-
(invoke [_ a1 a2 a3 a4]
301-
(.invoke ^IFn obj a1 a2 a3 a4))
302-
(invoke [_ a1 a2 a3 a4 a5]
303-
(.invoke ^IFn obj a1 a2 a3 a4 a5))
304-
(invoke [_ a1 a2 a3 a4 a5 a6]
305-
(.invoke ^IFn obj a1 a2 a3 a4 a5 a6))
306-
(invoke [_ a1 a2 a3 a4 a5 a6 a7]
307-
(.invoke ^IFn obj a1 a2 a3 a4 a5 a6 a7))
308-
(invoke [_ a1 a2 a3 a4 a5 a6 a7 a8]
309-
(.invoke ^IFn obj a1 a2 a3 a4 a5 a6 a7 a8))
310-
(invoke [_ a1 a2 a3 a4 a5 a6 a7 a8 a9]
311-
(.invoke ^IFn obj a1 a2 a3 a4 a5 a6 a7 a8 a9))
312-
(invoke [_ a1 a2 a3 a4 a5 a6 a7 a8 a9 a10]
313-
(.invoke ^IFn obj a1 a2 a3 a4 a5 a6 a7 a8 a9 a10))
314-
(invoke [_ a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11]
315-
(.invoke ^IFn obj a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11))
316-
(invoke [_ a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12]
317-
(.invoke ^IFn obj a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12))
318-
(invoke [_ a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13]
319-
(.invoke ^IFn obj a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13))
320-
(invoke [_ a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14]
321-
(.invoke ^IFn obj a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14))
322-
(invoke [_ a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15]
323-
(.invoke ^IFn obj a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15))
324-
(invoke [_ a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15 a16]
325-
(.invoke ^IFn obj a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15 a16))
326-
(invoke [_ a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15 a16 a17]
327-
(.invoke ^IFn obj a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15 a16 a17))
328-
(invoke [_ a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15 a16 a17 a18]
329-
(.invoke ^IFn obj a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15 a16 a17 a18))
330-
(invoke [_ a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15 a16 a17 a18 a19]
331-
(.invoke ^IFn obj a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15 a16 a17 a18 a19))
332-
(invoke [_ a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15 a16 a17 a18 a19 a20]
333-
(.invoke ^IFn obj a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15 a16 a17 a18 a19 a20))
334-
(invoke [_ a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15 a16 a17 a18 a19 a20 args]
335-
(.invoke ^IFn obj a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15 a16 a17 a18 a19 a20 args))
336-
(applyTo [_ args]
337-
(.applyTo ^IFn obj args)))))
267+
(binding [*next-id* (->next-id)]
268+
(let [[key root-registry] (key->key&registry key)
269+
270+
middlewares (concat [with-env
271+
with-ns
272+
root-registry]
273+
middlewares)
274+
registry (apply-middleware nil-registry middlewares)
275+
ctx {:registry registry
276+
:*stop-list (volatile! '())}
277+
obj (try-build ctx key)]
278+
^{:type ::root
279+
::print obj}
280+
(reify
281+
AutoCloseable
282+
(close [_]
283+
(->> (try-stop-started ctx)
284+
(throw-many!)))
285+
IDeref
286+
(deref [_]
287+
obj)
288+
Indexed
289+
(nth [_ i]
290+
(nth obj i))
291+
(nth [_ i not-found]
292+
(nth obj i not-found))
293+
(count [_]
294+
(count obj))
295+
ILookup
296+
(valAt [_ key]
297+
(get obj key))
298+
(valAt [_ key not-found]
299+
(get obj key not-found))
300+
IFn
301+
(call [_]
302+
(.call ^IFn obj))
303+
(run [_]
304+
(.run ^IFn obj))
305+
(invoke [this]
306+
(.invoke ^IFn obj))
307+
(invoke [_ a1]
308+
(.invoke ^IFn obj a1))
309+
(invoke [_ a1 a2]
310+
(.invoke ^IFn obj a1 a2))
311+
(invoke [_ a1 a2 a3]
312+
(.invoke ^IFn obj a1 a2 a3))
313+
(invoke [_ a1 a2 a3 a4]
314+
(.invoke ^IFn obj a1 a2 a3 a4))
315+
(invoke [_ a1 a2 a3 a4 a5]
316+
(.invoke ^IFn obj a1 a2 a3 a4 a5))
317+
(invoke [_ a1 a2 a3 a4 a5 a6]
318+
(.invoke ^IFn obj a1 a2 a3 a4 a5 a6))
319+
(invoke [_ a1 a2 a3 a4 a5 a6 a7]
320+
(.invoke ^IFn obj a1 a2 a3 a4 a5 a6 a7))
321+
(invoke [_ a1 a2 a3 a4 a5 a6 a7 a8]
322+
(.invoke ^IFn obj a1 a2 a3 a4 a5 a6 a7 a8))
323+
(invoke [_ a1 a2 a3 a4 a5 a6 a7 a8 a9]
324+
(.invoke ^IFn obj a1 a2 a3 a4 a5 a6 a7 a8 a9))
325+
(invoke [_ a1 a2 a3 a4 a5 a6 a7 a8 a9 a10]
326+
(.invoke ^IFn obj a1 a2 a3 a4 a5 a6 a7 a8 a9 a10))
327+
(invoke [_ a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11]
328+
(.invoke ^IFn obj a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11))
329+
(invoke [_ a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12]
330+
(.invoke ^IFn obj a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12))
331+
(invoke [_ a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13]
332+
(.invoke ^IFn obj a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13))
333+
(invoke [_ a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14]
334+
(.invoke ^IFn obj a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14))
335+
(invoke [_ a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15]
336+
(.invoke ^IFn obj a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15))
337+
(invoke [_ a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15 a16]
338+
(.invoke ^IFn obj a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15 a16))
339+
(invoke [_ a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15 a16 a17]
340+
(.invoke ^IFn obj a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15 a16 a17))
341+
(invoke [_ a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15 a16 a17 a18]
342+
(.invoke ^IFn obj a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15 a16 a17 a18))
343+
(invoke [_ a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15 a16 a17 a18 a19]
344+
(.invoke ^IFn obj a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15 a16 a17 a18 a19))
345+
(invoke [_ a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15 a16 a17 a18 a19 a20]
346+
(.invoke ^IFn obj a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15 a16 a17 a18 a19 a20))
347+
(invoke [_ a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15 a16 a17 a18 a19 a20 args]
348+
(.invoke ^IFn obj a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15 a16 a17 a18 a19 a20 args))
349+
(applyTo [_ args]
350+
(.applyTo ^IFn obj args))))))
338351

339352
(defn stop
340353
"Stops the root of a system"
@@ -493,24 +506,24 @@
493506
See `start`, `derive`."
494507
[target f & args]
495508
{:pre [(key? target)]}
496-
(let [prefix (gensym (str (symbol target) "+di-update-key#"))
497-
new-key (symbol (str prefix "-target"))
498-
f-key (symbol (str prefix "-f"))
499-
arg-keys (for [i (-> args count range)]
500-
(symbol (str prefix "-arg#" i)))
501-
new-factory (reify p/Factory
502-
(dependencies [_]
503-
(zipmap (concat [new-key f-key] arg-keys)
504-
(repeat :optional)))
505-
(build [_ deps]
506-
(let [t (deps new-key)
507-
f (deps f-key)
508-
args (map deps arg-keys)]
509-
(apply f t args)))
510-
(demolish [_ _]))
511-
own-registry (zipmap (cons f-key arg-keys)
512-
(cons f args))]
513-
(fn [registry]
509+
(fn [registry]
510+
(let [prefix (str (symbol target) "+di-update-key#" (*next-id*))
511+
new-key (symbol (str prefix "-target"))
512+
f-key (symbol (str prefix "-f"))
513+
arg-keys (for [i (-> args count range)]
514+
(symbol (str prefix "-arg#" i)))
515+
new-factory (reify p/Factory
516+
(dependencies [_]
517+
(zipmap (concat [new-key f-key] arg-keys)
518+
(repeat :optional)))
519+
(build [_ deps]
520+
(let [t (deps new-key)
521+
f (deps f-key)
522+
args (map deps arg-keys)]
523+
(apply f t args)))
524+
(demolish [_ _]))
525+
own-registry (zipmap (cons f-key arg-keys)
526+
(cons f args))]
514527
(fn [key]
515528
(cond
516529
(= new-key key)
@@ -536,18 +549,18 @@
536549
(di/start ::root (di/add-side-dependency `flyway))
537550
```"
538551
[dep-key]
539-
(let [*orig-key (volatile! nil)
540-
*orig-factory (volatile! nil)
541-
new-key (gensym "darkleaf.di.core/new-key#")
542-
new-factory (reify p/Factory
543-
(dependencies [_]
544-
;; array-map preserves order of keys
545-
{new-key :required
546-
dep-key :required})
547-
(build [_ deps]
548-
(new-key deps))
549-
(demolish [_ _]))]
550-
(fn [registry]
552+
(fn [registry]
553+
(let [*orig-key (volatile! nil)
554+
*orig-factory (volatile! nil)
555+
new-key (symbol (str "darkleaf.di.core/new-key#" (*next-id*)))
556+
new-factory (reify p/Factory
557+
(dependencies [_]
558+
;; array-map preserves order of keys
559+
{new-key :required
560+
dep-key :required})
561+
(build [_ deps]
562+
(new-key deps))
563+
(demolish [_ _]))]
551564
(fn [key]
552565
(when (nil? @*orig-key)
553566
(vreset! *orig-key key))

test/darkleaf/di/next_id_test.clj

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
(ns darkleaf.di.next-id-test
2+
(:require
3+
[clojure.test :as t]
4+
[darkleaf.di.core :as di]))
5+
6+
(defn a
7+
{::di/stop #(swap! % assoc :stop-id (di/*next-id*))}
8+
[]
9+
(atom {:start-id (di/*next-id*)}))
10+
11+
(t/deftest a-test
12+
(let [root (di/start `a)]
13+
(di/stop root)
14+
(t/is (= {:start-id 0 :stop-id 1} @@root))))

0 commit comments

Comments
 (0)