mount

fabrao 2016-09-26T06:15:27.000377Z

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

fabrao 2016-09-26T16:25:21.000384Z

I´m having problem starting threading with mount

tolitius 2016-09-26T16:41:53.000385Z

@fabrao: what problems are you having?

tolitius 2016-09-26T16:42:41.000386Z

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

tolitius 2016-09-26T16:43:18.000387Z

i.e.

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

tolitius 2016-09-26T16:43:46.000388Z

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

fabrao 2016-09-26T16:44:23.000389Z

but do I have to separate in two?

tolitius 2016-09-26T16:45:37.000390Z

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

fabrao 2016-09-26T16:45:58.000391Z

hummmm

tolitius 2016-09-26T16:46:02.000392Z

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

fabrao 2016-09-26T16:46:20.000394Z

I´ll give a try

fabrao 2016-09-26T16:46:24.000395Z

thanks

tolitius 2016-09-26T16:46:33.000396Z

sure, let me know if this solves your use case

fabrao 2016-09-26T17:10:44.000397Z

@tolitius It worked, many thanks

2016-09-26T18:35:41.000399Z

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?

manderson 2016-09-26T19:01:51.000402Z

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

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

manderson 2016-09-26T19:02:12.000403Z

where cli-config is your config map

2016-09-26T19:02:44.000404Z

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

manderson 2016-09-26T19:03:01.000405Z

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

manderson 2016-09-26T19:03:13.000406Z

mount/args will return the args you passed in

tolitius 2016-09-26T19:11:34.000407Z

@fabrao greats, thanks for the feedback

tolitius 2016-09-26T19:11:49.000408Z

@pmonks: there are a few ways

tolitius 2016-09-26T19:12:31.000409Z

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

tolitius 2016-09-26T19:13:08.000410Z

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

tolitius 2016-09-26T19:14:22.000412Z

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..

2016-09-26T19:21:06.000414Z

Nice - thanks @manderson, @tolitius!

2016-09-26T19:21:29.000415Z

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

2016-09-26T19:21:51.000416Z

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

2016-09-26T19:23:20.000417Z

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.

2016-09-26T19:23:51.000418Z

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

tolitius 2016-09-26T19:28:49.000419Z

@pmonks: 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

2016-09-26T19:29:32.000421Z

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.

tolitius 2016-09-26T19:29:37.000422Z

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..

2016-09-26T19:29:46.000423Z

👍

2016-09-26T19:30:13.000426Z

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

tolitius 2016-09-26T19:32:08.000428Z

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..

2016-09-26T19:41:54.000429Z

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?

2016-09-26T19:44:09.000431Z

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))))

dm3 2016-09-26T19:48:31.000434Z

you're not supposed to defstate in the functions

dm3 2016-09-26T19:48:39.000435Z

just (mount/start)

dm3 2016-09-26T19:49:24.000436Z

there's a version of start that takes arguments

dm3 2016-09-26T19:49:30.000437Z

(I think)

2016-09-26T20:17:29.000440Z

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).

dm3 2016-09-26T20:26:15.000443Z

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

tolitius 2016-09-26T20:32:16.000445Z

@pmonks: 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")))

tolitius 2016-09-26T20:33:48.000447Z

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)

2016-09-26T20:39:31.000449Z

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!).