Fork me on GitHub
#mount
<
2016-08-21
>
onetom05:08:24

aw... i was surprised there is no example app for yurt... i read the docs for a few times but i didn't catch the nuance in this sentence: > Working with a neo mount sample app that comes with Yurt sources and has 4 components (mount states):

onetom05:08:38

that comes with Yurt sources <-- i missed this one and i thought you are referring to the mount example neo app, so i didn't even click the link...

onetom05:08:39

thanks, i will investigate the example and i will get back with a more precise question

tolitius12:08:11

ah.. I should include the link in the docs.

tolitius12:08:32

sure. try it out, let me know if you have any questions

onetom16:08:48

pair@dusty ~/g/t/yurt> boot repl
nREPL server started on port 58064 on host 127.0.0.1 - 
REPL-y 0.3.7, nREPL 0.2.12
Clojure 1.8.0
Java HotSpot(TM) 64-Bit Server VM 1.8.0_102-b14
...
boot.user=>  (dev)
#'boot.core/temp-dir! was deprecated, please use #'boot.core/tmp-dir! instead
SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/Users/pair/.m2/repository/org/slf4j/slf4j-nop/1.7.7/slf4j-nop-1.7.7.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/Users/pair/.m2/repository/ch/qos/logback/logback-classic/1.1.3/logback-classic-1.1.3.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: See  for an explanation.
SLF4J: Actual binding is of type [org.slf4j.helpers.NOPLoggerFactory]
#object[clojure.lang.Namespace 0x2b0735fb "dev"]

dev=> (def dev-yurt (yurt/build (yurt/blueprint)))

clojure.lang.Compiler$CompilerException: java.lang.IllegalArgumentException: No implementation of method: :build of protocol: #'yurt.core/Hut found for class: yurt.core.Yurt, compiling:(boot.user31430876202986336.clj:1:15)
     java.lang.IllegalArgumentException: No implementation of method: :build of protocol: #'yurt.core/Hut found for class: yurt.core.Yurt

dev=> (def dev-yurt (yurt/build (yurt/blueprint)))
INFO  utils.logging - >> starting..  #'neo.conf/config
INFO  neo.conf - loading config from dev/resources/config.edn
INFO  utils.logging - >> starting..  #'neo.db/db
INFO  neo.db - conf:  {:datomic {:uri datomic:}, :www {:port 4242}, :nrepl {:host 0.0.0.0, :port 7878}}
INFO  neo.db - creating a connection to datomic: datomic:
INFO  utils.logging - >> starting..  #'neo.www/neo-app
INFO  neo.stager - staging the order book with 6 orders...
INFO  utils.logging - >> starting..  #'neo.app/nrepl
#'dev/dev-yurt

dev=> boot.core/*boot-version*
"2.6.0"

onetom16:08:28

not exactly successful out of the box

onetom16:08:59

if i do (def bp (yurt/blueprint)) first, then yurt/build, i get no error

onetom16:08:13

thats what you gave as an example here, but according to the Show me section of the yurt readme, this should work too:

dev=> (def dev-yurt (yurt/build (yurt/blueprint)))
INFO  neo.conf - loading config from dev/resources/config.edn
INFO  neo.db - conf:  {:datomic {:uri datomic:}, :www {:port 4242}, :nrepl {:host 0.0.0.0, :port 7878}}
INFO  neo.db - creating a connection to datomic: datomic:
#'dev/dev-yurt

onetom16:08:40

with the latest statble [mount "0.1.10"] im getting this error:

boot.user=>  (dev)
#'boot.core/temp-dir! was deprecated, please use #'boot.core/tmp-dir! instead

clojure.lang.Compiler$CompilerException: java.lang.RuntimeException: Unable to resolve var: mount.core/sigcont in this context, compiling:(utils/logging.clj:37:1)
             java.lang.RuntimeException: Unable to resolve var: mount.core/sigcont in this context

onetom16:08:31

and with mount-0.1.11-20160721.185126-8.jar i get the same error

onetom16:08:01

i tried with boot 2.7.0-rc1 too but i get this same sigcont error with mount 0.1.11-SNAPSHOT

onetom16:08:19

ok, if i comment out the resume/suspend related logging code utils/logging.clj:40-41, then (dev) starts with mount 0.1.10 but i still get the #'yurt.core/Hut error

onetom17:08:32

aside all of this, i think im getting an answer to my question original question regarding how mount+`yurt` differs from com.stuartsierra.component/system-map my fundamental misunderstanding about mount was that my application's public functions could just implicitly use the states defined by defstate and they wouldn't receive them as parameters, which is not the case. for example the db connection and the configuration are always explicit:

pair@dusty ~/g/t/s/neo> ag conn | ag defn
dev/neo/stager.clj:12:(defn stage-order-book [conn orders]
src/neo/db.clj:7:(defn- new-connection [conf]
src/neo/db.clj:14:(defn disconnect [conf conn]
src/neo/db.clj:24:(defn create-schema [conn]
src/neo/options/book.clj:5:(defn top-of-the-book [conn])
src/neo/options/book.clj:6:(defn price-levels [conn])
src/neo/options/book.clj:7:(defn book-depth [conn])
src/neo/www.clj:36:(defn start-neo [conn {:keys [www]}]     ;; app entry point
src/neo/options/orders.clj:5:(defn add-order [conn {:keys [ticker bid offer qty]}]
src/neo/options/orders.clj:12:(defn find-orders [conn ticker]
src/utils/datomic.clj:4:(defn entity [conn id]
src/utils/datomic.clj:7:(defn touch [conn results]

onetom17:08:06

states are only referenced directly from within other states:

pair@dusty ~/g/t/s/neo> ag -A 2 '\(defstate' | cat
src/neo/app.clj:13:(defstate nrepl :start (start-nrepl (:nrepl config))
src/neo/app.clj:14-                :stop (stop-server nrepl))
src/neo/app.clj:15-
src/neo/conf.clj:12:(defstate config
src/neo/conf.clj:13-  :start (load-config "dev/resources/config.edn"))
src/neo/conf.clj:14-
src/neo/db.clj:20:(defstate conn :start (new-connection config)
src/neo/db.clj:21-               :stop (disconnect config conn))
src/neo/db.clj:22-
src/neo/www.clj:43:(defstate neo-app :start (start-neo conn config)
src/neo/www.clj:44-                  :stop (.stop neo-app))  ;; it's a "org.eclipse.jetty.server.Server" at this point

onetom17:08:23

so from the point of the "public api" of an application, the difference between system and mount+yurt is the app functions doesn't receive a full yurt, just the necessary components but individually, not as a hash map.

dm320:08:28

@onetom: in my apps that use Mount, the public APIs don't receive the states as arguments - why would they?

dm320:08:51

it's your choice whether to do that or use the states implicitly

dm320:08:37

I even do the same with the "legacy" system approach where the system is stored in a known place and I have a defsysfn macro which allows things like

(defsysfn calculate
   :using {calculator calculators/AdvancedCalculator}
   [& args]
   (calc/add calculator args)

dm320:08:07

which gets the instance of the calculators/AdvancedCalculator protocol or what have you from the system map