mount

bill 2017-02-01T21:50:17.000615Z

just found mount 🎉 been looking for ways to manage state without passing an extra parameter to every function (so Component’s out) Question: if I want to use Mount to e.g. connect to two databases at once, would I use Yurt for that? Say I want to run a database upgrade, reading from one database and writing to another.

tolitius 2017-02-01T21:51:01.000616Z

hey @bill, good find 🙂

tolitius 2017-02-01T21:51:19.000617Z

if these are two different databases, they are two different states

tolitius 2017-02-01T21:51:30.000618Z

i.e. you can use mount

tolitius 2017-02-01T21:52:20.000619Z

(defstate from-db :start (connect {...}) :stop ...)
(defstate to-db :start (connect {...}) :stop ...)

bill 2017-02-01T21:53:22.000620Z

thanks @tolitius I need to clarify…

bill 2017-02-01T21:56:21.000621Z

(lame pseudo-code on its way…)

tolitius 2017-02-01T21:56:46.000622Z

sure, let's see it

bill 2017-02-01T21:58:08.000623Z

(ns db-access
  (:require [my-ns :refer [db]]))

(defn people
  (query db "select * from people"))

(defn people-add [peeps]
  (bulk-insert db "insert into people" peeps))

bill 2017-02-01T21:58:37.000626Z

I have a single db access namespace that calls some db library to do the actual interaction

bill 2017-02-01T21:59:05.000627Z

so I’d use Mount to produce/consume the db connection parameters

tolitius 2017-02-01T21:59:53.000628Z

yea, unless I am missing something, you are using a single state (i.e. a single connection, a single resource) that you use to perform different actions: select, insert, update...

bill 2017-02-01T22:00:16.000629Z

ya and that state has to be different for each database cnxn

tolitius 2017-02-01T22:00:16.000630Z

if that's correct, mount will connect to this database and will be out of your way

tolitius 2017-02-01T22:01:12.000631Z

ah.. hold on. you are using db access for more than one database in the same runtime?

bill 2017-02-01T22:03:10.000632Z

yes, here is what it would look like with naive code:

(ns db-access)

(defn people [db]
  (query db "select * from people"))

(defn people-add [db peeps]
  (bulk-insert db "insert into people" peeps))

(ns top
  (:require [db-access :refer [people people-add]]))

(def db-from “something-something”)
(def db-to “something-else-entirely”)

(defn transfer [db-from db-to])
  (people-add db-to (people db-from))

bill 2017-02-01T22:03:39.000633Z

wanna eliminate the first parameter (`db`) from each function in the db-access ns

bill 2017-02-01T22:04:40.000634Z

seems like I’d have to spin up two Yurts and make transfer call into the first one to get the people and then call into the second one to insert the people

tolitius 2017-02-01T22:08:41.000636Z

you could. by why not people [db]? 🙂

tolitius 2017-02-01T22:11:49.000637Z

I would recommend using the args:

(defn people [db]
  (query db "select * from people"))
since no matter how you manage your state:
(defn people []
  (query db "select * from people"))
will always use the same db (the same connection / resource). i.e. not really mount or really mount or component specific there is one gotcha to this, which is, in testing, or for different use case, you can use mount/start-with: https://www.dotkam.com/2016/01/17/swapping-alternate-implementations-with-mount/

bill 2017-02-01T22:13:55.000639Z

ok thanks @tolitius. I clearly misunderstand Mount and need to go study more. I thought the whole point was to eliminate the configuration parameter (`db` in this case) from my argument lists, allowing me to refer to the configuration parameter(s) (from within my function bodies) as if they were in the enclosing environment

tolitius 2017-02-01T22:30:35.000642Z

you mean like local scoping?