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):
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...
thanks, i will investigate the example and i will get back with a more precise question
ah.. I should include the link in the docs.
sure. try it out, let me know if you have any questions
pair@dusty ~/g/t/yurt> boot repl
nREPL server started on port 58064 on host 127.0.0.1 - <nrepl://127.0.0.1:58064>
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 <http://www.slf4j.org/codes.html#multiple_bindings> 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:<mem://yurt>}, :www {:port 4242}, :nrepl {:host 0.0.0.0, :port 7878}}
INFO neo.db - creating a connection to datomic: datomic:<mem://yurt>
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"
not exactly successful out of the box
if i do (def bp (yurt/blueprint))
first, then yurt/build
, i get no error
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:<mem://yurt>}, :www {:port 4242}, :nrepl {:host 0.0.0.0, :port 7878}}
INFO neo.db - creating a connection to datomic: datomic:<mem://yurt>
#'dev/dev-yurt
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
and with mount-0.1.11-20160721.185126-8.jar
i get the same error
i tried with boot 2.7.0-rc1
too but i get this same sigcont
error with mount 0.1.11-SNAPSHOT
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
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]
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
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.
@onetom: in my apps that use Mount, the public APIs don't receive the states as arguments - why would they?
it's your choice whether to do that or use the states implicitly
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)
which gets the instance of the calculators/AdvancedCalculator
protocol or what have you from the system map