Created
November 26, 2021 15:08
-
-
Save arichiardi/37563efedcfb69bae28d3577a7c1b891 to your computer and use it in GitHub Desktop.
Integrant/Duct dev/prod app -main code
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;; This setup solves the problem of prod and dev code path differing at startup. | |
;; The above issue leads to problems hard to catch, catch when deploying to prod. | |
;; | |
;; in production main | |
;; | |
(def duct-config-file-path (io/resource "/<project>/config.edn") | |
(defn prep-config | |
"Duct prep-config wrapper." | |
[profiles config-path] | |
(-> (duct/read-config config-path) | |
(duct/prep-config profiles))) | |
(defn -main | |
[& args] | |
(logging/info ascii-banner {:args (vec args)}) | |
(let [{:keys [options]} (cli/parse-opts args cli-options) | |
config-override-path (:config options) | |
config-path (or (some-> config-override-path io/file) duct-config-file-path) | |
profiles (->> (:profile options) | |
(keyword "duct.profile") | |
vector)] | |
(logging/info "Application is starting" | |
{:options options :config-path config-path :profiles profiles}) | |
(alter-var-root #'types/*warn-on-invalid-specs* (constantly false)) | |
(let [system (-> (prep-config profiles config-path) | |
(ig/init [:duct/daemon]))] | |
;; NOTE: we do not want to block when we are in dev mode (a REPL is started). It is the REPL | |
;; that will block the process from exiting. | |
(when-not (appserver.system/dev? system) (duct/await-daemons system)) | |
system))) | |
;; | |
;; In dev.clj or user.clj | |
;; | |
(ir/set-prep! #(web.main/prep-config web.main/system-config-file [:duct.profile/dev])) | |
(def ^:const dev-banner "+-+-+-+-+-+-+-+ |) [- \\/ +-+-+-+-+-+-+-+") | |
(defn scan-dirs-as-of-now | |
"Trigger a clojure.tools.namespace scan at the current time. | |
In order to avoid a hefty first reload we scan for file modifications | |
from now so that the clojure.tools.namespace thinks that there are no | |
modified files - we just started the application after all." | |
[refresh-tracker] | |
(-> refresh-tracker | |
(assoc :clojure.tools.namespace.dir/time (System/currentTimeMillis)) | |
(ctn-dir/scan-dirs ctn-repl/refresh-dirs {:platform ctn-find/clj}))) | |
(defn -main | |
[] | |
(logging/info dev-banner) | |
;; | |
;; Prepare Integrant config | |
;; | |
(ir/prep) | |
;; | |
;; Delegate system startup to the "production" code path and fill system in | |
;; | |
(alter-var-root #'integrant.repl.state/system (fn [_] (web.main/-main "--profile" "dev"))) | |
;; | |
;; Manually initialize clojure.tools.namespace machinery | |
;; | |
(let [refresh-tracker (alter-var-root #'ctn-repl/refresh-tracker scan-dirs-as-of-now) | |
refresh-stats | |
{:namespace-count (count (vals (:clojure.tools.namespace.file/filemap refresh-tracker))) | |
:updated-file-count (count (:clojure.tools.namespace.dir/files refresh-tracker)) | |
:refreshed-at (->> refresh-tracker | |
:clojure.tools.namespace.dir/time | |
(tcoerce/from-long) | |
(tformat/unparse (tformat/formatter :rfc822)))}] | |
(logging/info "Development system started" | |
(merge refresh-stats | |
(when (logging/enabled? :debug) | |
{:started-keys (into [] (keys integrant.repl.state/system))}))))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment