juxt

onetom 2020-02-27T09:04:27.028900Z

im trying to make a throw-away datomic system using juxt/clip and try to clean up the created tmp db after stopping it. i can't seem to figure out how can i pass a (clip/ref) within the :stop operation:

(defn default-schema-from-file []
  (->> "datomic-schema.edn" io/resource slurp edn/read-string))

(defn tmp-in-mem-uri [] (str (gensym "datomic:<mem://tmp>-")))

(defn cleanup [uri conn]
  (prn [uri conn]) 
  (d/release conn)
  (d/delete-database uri))

(defn tmp-parts []
  {:datomic/schema
   {:start `(default-schema-from-file)}

   :datomic/uri
   {:start `(tmp-in-mem-uri)}

   :datomic/conn
   {:pre-start  `(d/create-database (clip/ref :datomic/uri))
    :start      `(d/connect (clip/ref :datomic/uri))
    :post-start `(d/transact ~'this (clip/ref :datomic/schema))
    :stop       `(cleanup (clip/ref :datomic/uri) ~'this)}})

onetom 2020-02-27T09:11:04.030100Z

that (prn [uri conn]) debug statement prints:

[(clip/ref :datomic/uri) #object[datomic.peer.LocalConnection 0x63235b75 "datomic.peer.LocalConnection@63235b75"]]
so the ~'this gets resolved as I expected but the (clip/ref :datomic/uri) doesn't

dominicm 2020-02-27T09:14:25.030900Z

I think there's a comment in the source about confirming refs in stop make sense.

onetom 2020-02-27T09:18:53.033600Z

yeah, i can see how it can pose unreconcilable constraints on the start/stop ordering... but in this case what shall i do? sounds like i would need to carry the dependencies of the stop process within the started component. but then will that component be still valid when im stopping the system?... 😕

onetom 2020-02-27T09:21:08.034400Z

or i could try to tease out this info from the connection object using something like this:

(.dbname ^datomic.peer.LocalConnection (sys :datomic/conn))
=&gt; "tmp-17692"

onetom 2020-02-27T09:34:47.035800Z

i was trying to "inline" my small cleanup function as:

:stop       `(do (d/release (:conn ~'this))
                     (d/delete-database (:uri ~'this)))
then I got this error:
Execution error (ExceptionInfo) at juxt.clip.impl.core/evaluate-pseudo-clojure$fn (core.cljc:187).
Got null for function looking up symbol: do
this pseudo eval thing is quite fragile 😕 still no idea though how could be it done better...

onetom 2020-02-27T09:37:07.036400Z

this feels like an ok compromise:

(defn cleanup-conn&amp;db [{:keys [uri conn]}]
  (d/release conn)
  (d/delete-database uri))

(defn tmp-parts []
  {:datomic/schema
   {:start `(default-schema-from-file)}

   :datomic/uri
   {:start `(tmp-in-mem-uri)}

   :datomic/conn
   {:pre-start  `(d/create-database (clip/ref :datomic/uri))
    :start      `{:uri  (clip/ref :datomic/uri)
                  :conn (d/connect (clip/ref :datomic/uri))}
    :resolve    :conn
    :post-start `(d/transact (:conn ~'this) (clip/ref :datomic/schema))
    :stop       `(cleanup-conn&amp;db ~'this)}})

(comment
  @(def sys-config {:components (tmp-parts)})
  @(def sys (clip/start sys-config))
  (clip/stop sys-config sys)
)

onetom 2020-02-27T10:46:43.038600Z

hmm... im also wondering how can i make this thing more modular, so i can create multiple datomic connections. the use-case would be to create a migration program, which transforms one datomic db into another one. but then i would need uri/schema/conn for each instance... so a started system would look something like this:

{:source-123/schema [,,,]
 :source-123/uri    "datomic:<dev://source-123>"
 :source-123/data   {:uri  "datomic:<dev://source-123>"
                     :conn ^datomic.peer.Connection []}

 :dest-234/schema   [,,,]
 :dest-234/uri      "datomic:<dev://dest-234>"
 :dest-234/data     {:uri  "datomic:<dev://dest-234>"
                     :conn ^datomic.peer.Connection []}}

dominicm 2020-02-27T12:50:28.039100Z

Macros don't work, yeah :)

dominicm 2020-02-27T12:50:49.039500Z

I didn't want a full clojure interpreter.

dominicm 2020-02-27T12:51:12.040200Z

I wanted something that wasn't inventing a new syntax/form that wrapped function calls.

👍 1
dominicm 2020-02-27T12:51:56.040800Z

I think modularity and repetition is something I would address via transforms. This is essentially "tagging" your component with a key and having postwalk update it in some way.