mount

Ed 2025-03-03T12:35:30.231209Z

Hi. I've picked up a codebase that uses mount, and I have very little experience with it. I have a server that is having trouble starting after a database failure. If I connect to a repl on that vm, I can see that the context reference is returning #object[mount.core.DerefableState 0x49372eea {:status :pending, :val nil}] and has been in that state for a while. Is there a way to introspect the current state and work out what's going on?

tolitius 2025-03-03T15:27:57.633009Z

DerefableState https://github.com/yogthos/clojure-error-message-catalog/blob/master/lib/mount/derefablestate-cannot-be-cast-to-ifn.md it was not (could not be) started i.e. a reference does not have the actual state to point to:

tolitius 2025-03-03T15:29:16.655139Z

a state usually refers to a function that returns it so *if you see a problem with it being started you can just inspect that function:

(defstate conn :start (create-conn)
               :stop (disconnect conn))
e.g. create-conn 👆

Ed 2025-03-03T15:33:38.370709Z

in an effort to debug the problem, I have wrapped each of the blocks of code in the defstate :start locations in try/catch and included some prn's - I don't see any of the output. The main entrypoint for the app looks like this

(defn -main [& args]
  (prn 'starting (Date.))
  (try
    (mount/start-with-args {:config "config/prod.edn"})
    (finally
      (prn 'mount 'done)))
  (prn 'started (Date.)))
and the last thing I see in the output is 2025-03-03T15:26:20Z app[e82de15a094d78] sin [info]starting #inst "2025-03-03T15:26:20.986-00:00"

Ed 2025-03-03T15:35:49.720619Z

there are several things defined with defstate dotted around the code. How do I tell which one is in a borked state? I'm assuming that mount is trying to start the app and that's why it's not returned yet.

Ed 2025-03-03T15:37:08.672839Z

Thanks for your help, btw ...

tolitius 2025-03-03T15:44:08.130029Z

a few things

(mount/start-with-args {:config "config/prod.edn"})
starts all the stateful components, not a particular one if one of the states throws an exception you would see it in logs / REPL depending on how it is handled:

tolitius 2025-03-03T15:44:49.020349Z

mount does not really add or remove anything from function invocation that create stateful components (would help to go through https://github.com/tolitius/mount/blob/master/README.md to understand what the role of it is in the app start) a quick way could be to add https://github.com/tolitius/mount-up to watch the states being started / stopped but it is really inside the functions that start the stateful components vs. mount where I would recommend looking

Ed 2025-03-03T15:49:08.801379Z

ok. thanks. The code that's run in each of the :start blocks doesn't seem to output anything, so I'm a little puzzled as to what's causing the app to hang. I'll keep digging. thanks for your help

👍 1