@dm3: sure, you can do that if you don't use yurt
, because then you are running your tests and dev app in separate processes, so it's okay for your defstate
s to be singletons, since there is only one app running at a time.
the whole point of yurt
(or stuart sierra component) is to allow multiple apps within the same jvm runtime, so you can run your tests within your dev process (which as we know, tolitius doesn't endorse; thanks for that article!)
with defsysfn
I use a macro for tests that rebinds the system
var to whatever I need. I guess you could do the same with yurt, although the mount states would be scattered everywhere...
@onetom: in "Building Yurts" docs section:
Before building local Yurts based on a mount application a "blueprint" needs to be created
"Show me" section creates a blueprint first before a call to (yurt/build (yurt/blueprint))
But I see where the confusion could come from. The internal complication is that (yurt/blueprint)
extends the protocol and it needs to be done first, before a call to (yurt/build)
.
thanks for checking yurt out with mount 0.1.10
. I just updated it, so you should be able to get the latest mount with yurt 0.1.0
.
about explicit vs. implicit parameters to API:
as @dm3 mentioned this is up to a developer (you) and the design of API. You can pass the state explicitly to the API as well as close over that state by not explicitly passing it in the arguments, it's up to you. This choice applies to both: yurt and mount. The only gotcha in yurt are stateful macros (i.e. compojure's defroutes
) as we discussed earlier.@tolitius: thanks a lot for the clarifications!
regarding closing over states: wouldn't such an api design negate the benefit of having multiple yurts?
btw, i've seen the the app.sms/send-sms
solution, where a state is a function closing over other states. im still thinking about the implications of that.
@tolitius: i see you released yurt:0.1.0
into clojars but forgot to push it to github:
https://github.com/tolitius/yurt/commit/5979a37ab855fe6c63afbeaa6cbee8058d1c7a6a is 404
@onetom: yep, already pushed, did not have a good connection while releasing.
as to "closing over states": I agree, you would most likely want your API to take state as arguments (explicitly) when using yurt. With mount it would be totally up to you, but with yurt explicit arguments is the way to go. Let me explain a bit further:
the way yurt works, it takes all the states (defined with defstate
), builds them by calling their :start
functions, and then detaches these states from their corresponding vars, which gives you back a set of ready to use components that you can pass at your application edges (i.e. compojure routes) which would propagate these components down to all the functions that take them explicitly.
the idea behind yurt, as you mentioned before, was to show that mount states can also be used to run multiple "systems" within the same JVM. The only legible reason I've seen for this would be to run your tests within the dev REPL, and while I respect this flow, it does not work well (at least for me) especially with lein
which relies on global state of the artifacts, which makes you waste time in REPL before realizing "lein just needed to be cleaned".
Having said that, yurt can still be used if you need that "multiple systems within the same JVM". You can still use the same mount states, but you would be the one passing these states to all the functions: i.e. can no longer rely on Clojure's :require
to bring these states in for the namespaces to use.
@tolitius: thanks for the crystal clear explanation!
sure, always welcome 🙂