Fork me on GitHub
#mount
<
2016-09-26
>
fabrao06:09:27

Hello all, I know that the compiler define the order of creation, but is there any way to define the order manually?

fabrao16:09:21

I´m having problem starting threading with mount

tolitius16:09:53

@fabrao: what problems are you having?

tolitius16:09:41

you can control the start order by simply starting states explicitly vs. starting all with (mount/start)

tolitius16:09:18

i.e.

(mount/start #'app.a #'app.c)
(mount/start #'app.b #'app.d)

tolitius16:09:46

will start a and c first, and then b and d

fabrao16:09:23

but do I have to separate in two?

tolitius16:09:37

yes, if you do (mount/start) or (mount/start #'app.a #'app.c #'app.b #'app.d), it will start all 4 states (given that you only have these four) in the order they were discovered by the compiler

tolitius16:09:02

think about it as (mount/start "set" of states)

fabrao16:09:20

I´ll give a try

tolitius16:09:33

sure, let me know if this solves your use case

fabrao17:09:44

@tolitius It worked, many thanks

deactivateduser18:09:41

G'day! My apologies if this has been asked before (fwiw I spent a bit of time searching, but didn't find anything that seemed relevant). Is there an established way of having config specified via the command line (come in through -main [& args]), but be handled from that point onward as "normal" mount state?

manderson19:09:51

@deactivateduser10790 we just pass it in using mount's with-args in our -main:

(->
  cli-config
  mount/with-args
  mount/start)

manderson19:09:12

where cli-config is your config map

deactivateduser19:09:44

How do I refer to cli-config from other namespaces?

manderson19:09:01

If you want to combine that with a static edn file or something you can simply merge them in a config state using mount/args

manderson19:09:13

mount/args will return the args you passed in

tolitius19:09:34

@fabrao greats, thanks for the feedback

tolitius19:09:31

1. mount/args is one, but this would be "global" per app: i.e. any ns will be able to access it without requiring anything

tolitius19:09:08

2. another one would be to use a known config path (or just pass this path via mount/args), but use it to create a state: https://github.com/tolitius/stater/blob/master/smsio/src/app/conf.clj#L12-L13

tolitius19:09:22

3. another would be to use something like cprop: https://github.com/tolitius/cprop where you can use all the -Dconf=config-path (or any system props), or env vars, or classpath resource, etc..

deactivateduser19:09:29

Yeah I like the idea of require as the dependency graph of states, and would like to preserve that if I can.

deactivateduser19:09:51

(also because I want different "components" to be able to define additional state based on this config state)

deactivateduser19:09:20

cprop sounds interesting, though I don't like System properties much - I tend to use tools.cli to handle this kind of thing as "real" CLI parameters.

deactivateduser19:09:51

But great pointers - you've gotten me moving again!

tolitius19:09:49

@deactivateduser10790: sure, sys props is just one of many venues to get config(s). I usually just use a single config file (`.edn`) and override props at runtime depending on environment with ENV vars (just one way to do it). there are also cursors in cprop that I use a bit to not have to destructure very nested configs in multiple places: https://github.com/tolitius/cprop#cursors

deactivateduser19:09:32

Ah ok - and yeah my plan is to have a single central config file, with a single CLI arg that points to it at runtime.

tolitius19:09:37

configuring apps is an interesting subject, and also quite opinionated in our community 🙂 I prefer to use whatever makes sense for a given problem with no ground rules like 12 factor and others..

deactivateduser19:09:13

Bootstrapping is one place where things get squirrelly, I've found. 😉

tolitius19:09:08

right, just try several different approaches, see what works best, I found just slurping .edn works great for little apps, whereas a config lib (i.e. cprop) comes very handy for larger apps: different modules, dockerized and overriden by envs, etc..

deactivateduser19:09:54

So am I right in thinking I could do something like (defstate config :start (load-config)) ? Could this be done within a (def -main ..., so that I can set the :file based on CLI opts?

deactivateduser19:09:09

e.g. something like (not code checked, so probably contains syntax errors):

(defn -main [& args]
  (let [config-file (parse-args args)]
    (defstate config :start (load-config :file config-file))))

dm319:09:31

you're not supposed to defstate in the functions

dm319:09:39

just (mount/start)

dm319:09:24

there's a version of start that takes arguments

dm319:09:30

(I think)

deactivateduser20:09:29

Ok. I guess I'm still not clear on how I can parse the args passed to -main, then put them in a mount state (which can be depended upon by other states via standard require).

dm320:09:15

https://github.com/tolitius/mount#be-composing says you need to

(defstate config :start (load-config :file (mount/args)))

(defn -main [& args]
  (-> (parse-args args)
          (mount/with-args)
          (mount/start)))
or something like that

tolitius20:09:16

@deactivateduser10790: is (load-config) your function or is it coming from a library (i.e. cprop)? If it is coming from cprop, it would work without needing to pass runtime mount/args, as cprop would look in two places for configuration files: * classpath: for the config.edn resource * file system: for a path identified by the conf system property (i.e. the one you can pass via -Dconf=[path]) in case the (load-config) is your function, you could just access the system property directly:

(defn load-config [path]
  (info "loading config from" path)
  (-> path 
      slurp 
      edn/read-string))

(defstate config 
  :start (load-config (System/getProperty "conf")))

tolitius20:09:48

given that conf is your property with a path to the your-config.edn file (i.e. -Dconf=/opt/app/yourapp/conf/app-conf.edn << an example path)

deactivateduser20:09:31

Yeah the challenge is that I need to parse the args passed into -main in order to know what path to call load-config with. It looks like mount's with-args fn might be the missing link I'm looking for though (thanks @dm3!).