we are using the same approach too, except, instead of a clojure.core/delay
, we are using a redelay
, which allows us to even re-initialize our service.
since we also start an nREPL server and open up a socket REPL port on our ion instances, it’s possible to modify the function, which constructs our ring router, without redeployment.
but then , which is baked into the :http-direct :handler-fn
(specified in the ion-config.edn
)
(ns our.ion
(:require
[datomic.ion :as ion]
,,,
[redelay.core :as redelay])
(:import
(redelay.core State)))
(def env (-> (ion/get-env) :env (or :local)))
(def replion (replion/start env)) #_(.close replion)
(defonce ^State cfg-ref (redelay/state (api.env/cfg env)))
(defn cfg [] (deref cfg-ref))
(defonce ^State svc-ref (redelay/state (svc/mk (cfg))))
(defn svc [] (deref svc-ref))
(defonce ^State ring-handler-ref
(redelay/state (ring-api/mk-handler cfg-ref svc-ref)))
(defn ring-handler [req] (@ring-handler-ref req))
then, if we want to re-read the config from SSM or want to recompute our ring router, we can eval the following thru our ion REPL (aka REPLion) connection:
(do (.close cfg-ref)
(.close svc-ref)
(.close ring-handler-ref))
This approach has the benefit of making this our.ion
NS always loadable, even if the initialization functions (api.env/cfg
, svc/mk
, ring-api/mk-handler
) would fail.
Since we initialize a REPL server early on, we can debug such failures through a REPL client.
If this NS would fail to load, then it’s retried a few times, then a CodeDeploy rollback gets triggered. Including the deployment time, it could take 5-10minutes to get back to a working state.