Component Lifecycle Services

Clojure has several library to manage the lifecycle of components that make up the application, especially those components with state. Components can be started and stopped in a specific order.

Example component lifecycle libraries included

Configure a deps.edn project

Set up a project to work with component lifecycle service, for example by adding components to the dev.clj file under a dev directory.

To load the service code automatically, add require and in-ns expressions to dev/user.clj and use the -A:dev alias when starting the REPL from Spacemacs.

Example project with component lifecycle

Using mount, its common to define a dev.clj file with go, stop and restart functions that manage the lifecycle of mount components. A start function contains the list of components with optional state.

(defn start []
  (with-logging-status)
  (mount/start #'app.conf/environment
               #'app.db/connection
               #'app.www/business-app
               #'app.service/nrepl))

The go function calls start and marks all components as ready.

(defn go
  "Start all states defined by defstate"
  []
  (start)
  :ready)

The stop function stops all components, removing all non-persistent state.

(defn stop [] (mount/stop))

The reset function that calls stop, refreshes the namespaces so that stale definitions are removed and starts all components (loading in any new code).

(defn reset
  "Stop all states defined by defstate.
  Reload modified source files and restart all states"
  []
  (stop)
  (namespace/refresh :after 'dev/go))

Configure cider-refresh to use component lifecycle

Create a .dir-locals.el file that calls the relevant mount functions when using cider-refresh.

SPC p e to open a .dirs.locals.el in the current project, creating the file if it does not exist.

During development call the reset function to stop components, clean the namespace and start all components again.

((clojure-mode . ((cider-refresh-before-fn . "practicalli.dev/reset"))))

SPC f s to save the file. Refresh a buffer from the project or open a new file to trigger the reading of the .deir-locals.el configuration by Emacs.

Alternatively, if a namespace refresh is not required, configure the .dirs-local.el file to call stop then start.

((clojure-mode . ((cider-refresh-before-fn . "practicalli.dev/stop")
         (cider-refresh-after-fn . "practicalli.dev/start"))))

This code calls the stop function from the component lifecycle library at the start of the cider-refresh function. At the end of cider-refesh, the start function is called to restart all the components in the defined order in the project.

TODO:

TODO:

Prevent cider-ns-refresh calling component lifecycle functions

C-- , e n or SPC u - 1 , e n calls cider-ns-refresh but prevents the refresh functions defined in cider-ns-refresh-before-fn and cider-ns-refresh-after-fn from being invoked.

Reference

results matching ""

    No results matching ""