I am having a bit of a chicken-or-the-egg problem. I created a tiny implementation to illustrate the issue. Details in thread.
(ns bbmcp
(:require [clojure.pprint :refer [pprint]]
[integrant.core :as ig]))
(defn in2out
([]
(in2out *in* *out*))
([reader writer]
(loop []
(let [line (.readLine reader)]
(.write writer (str line "\n"))
(flush))
(recur))))
(def config
{:adapter/in2out {:blah 1}})
(defmethod ig/init-key :adapter/in2out [_ {:keys [blah] :as opts}]
(in2out))
(defmethod ig/halt-key! :adapter/in2out [_]
(println "Shutting down...")
(System/exit 0))
(defn -main [& args]
(println "Args:")
(pprint args)
(.addShutdownHook (Runtime/getRuntime) (Thread. (fn [] (ig/halt! system))))
(def system (ig/init config)))
(comment
(apply -main [1 2 3])
(pprint [1 2 3]))
If I move the system definition up 1 line it works, but the shutdown hook is never defined because the init runs a loop.I tried using {} and nil for system in the halt! but it gives exceptions because it is not an integrant init object.
The real app I am creating will need to do cleanup from the shutdown hook, this is just a toy implementation to play with and show the issue.
The in2out function should run its loop in a separate thread. Integrant expects the init-key method to return before moving onto the next key, so having an infinite loop during initiation will prevent any keys that depend on :adapter/in2out from being run.