Fork me on GitHub
#mount
<
2017-12-04
>
madvas21:12:32

Guys how so mount doesn’t support async start/stop. For example, if I need to load config asynchronously. How is that usually handled?

tolitius21:12:53

@madvas can you describe what you are trying to do?

madvas21:12:35

I need to load some configuration from locally running blockchain (understand server). Cannot be done in sync way. Other components might need this configuration data in their :start function

tolitius21:12:17

so other components won't be able to start until the config is loaded?

madvas21:12:50

no, they need loaded information

tolitius21:12:54

right, so what makes it async?

madvas21:12:41

not sure what you mean. that request to locally running server to fetch config. It’s separate app from the cljs app

tolitius21:12:32

ok, so you have two apps?

tolitius21:12:10

one in cljs and another one is clj (i.e. backend)

tolitius21:12:40

and you need to load configuration from the server whenever someone visits a page / or the cljs app starts?

madvas21:12:23

no, it’s different. Have just one, it’s cljs nodejs app, the other one is blockchain, it’s 3rd party software beyond my control

tolitius22:12:34

ok, and you need to load config from a 3rd party app (i.e. a server) on cljs nodejs app's start?

tolitius22:12:15

mount will respect the order of states that need to be started, which means components which need this configuration will wait until a component that loads it from the server is started. i.e. if you have something like:

(defstate config :start (load-it-from-server ""))
and other components depend on this config they will wait

tolitius22:12:04

from what you described so far I don't see what is "async" about it

madvas22:12:15

but load-it-from-server returns what? you mean to do it like synchronous load?

madvas22:12:47

the thing is that library to interact with blockchain server doesn’t support synchronous requests. Must pass callback

tolitius22:12:30

right, so you can put it in a channel once the response is received. pseudo code:

(let [c (async/chan)]
  (http/get url #(>!! c %))
  (<!! c))

tolitius22:12:19

I would wrap it in a load-it-from-server function, with a better name of course

madvas22:12:48

there’s no >!! and <!! in cljs

madvas22:12:57

only non-blocking

tolitius22:12:35

ah.. cljs that's right, single event loop. then you would provide a callback that does (mount/start). once the config is loaded, mount will start all the components

madvas22:12:12

I see, that’s what I started thinking, okay I’ll figure out something, thank you very much for your time 😉

tolitius22:12:42

sure, sorry took some time to understand where you are coming from

tolitius22:12:51

something that can be useful: (-> (with-args {:config ....}) (mount/start))

tolitius22:12:16

since once you receive the config you need to pass it to all other components

madvas22:12:09

yeah, I have that in mind, thanks but would be nice if I could just pass channel or something to defstate and it would wait with execution until results come and then pass it

tolitius22:12:10

might be useful only for cljs side. and not in defstate, since the waiting should happen outside of mount: i.e. before calling (mount/start)

madvas22:12:43

I think there’s more use cases where async start might be useful and cannot be done before mount/start. But yeah, clj’s advantage over cljs here is that it can make any asynchronous call synchronous