This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2016-01-24
Channels
- # aatree (27)
- # admin-announcements (5)
- # all-the-channels (2)
- # aws (27)
- # beginners (38)
- # boot (48)
- # braid-chat (18)
- # cider (6)
- # cljs-dev (9)
- # cljsrn (8)
- # clojars (4)
- # clojure (73)
- # clojure-dev (2)
- # clojure-russia (2)
- # clojure-sg (1)
- # clojurescript (96)
- # code-reviews (3)
- # community-development (4)
- # conf-proposals (17)
- # core-matrix (2)
- # cursive (2)
- # datascript (4)
- # datomic (4)
- # dirac (1)
- # funcool (5)
- # hoplon (2)
- # mount (66)
- # off-topic (35)
- # om (211)
- # parinfer (2)
- # pedestal (2)
- # proton (1)
- # reagent (2)
@tolitius it is expensive in the sense that it hits an api with a limit, the limit might not be a problem but I live in China, which means I don't have the best connectivity when I travel so I like to be able to keep state unreloaded as with an atom in defonce. Actually travel or not, internet to outside the Chinese firewall is unstable. Even the (albeit small unimportant) Google office in Shanghai didn't have decent internet, hahah.
I do change the data in the process, so it is kinda ephemeral. I do save it to be application state though.
looks like there are two things:
* this state is mutable
* the restart / reload is "expensive"
I don't have a good answer.. need to think about it..
looks like the usage implies some kind of start-with
path, where you call the real API cache/persist data and then do start-with {#'your/state this-cache}
. when you want to refresh that data from API, you would just call start
... just thinking out loud without knowing the actual context
also mount should not "restart" a state if you recompile namespace(s) not associated with it
did not add docs for it yet, but start-with
now takes values as substitutes. start-with-states
takes states as substitutes.
Wow, quick turnaround. I can separate the state to a different namespace then didn't try that one yet.
That was what I was slightly confused about, I don't need to call start anywhere in this project and defstates will still work.
@bbss: yes, in cljs, you are probably running in cljc
mode? which would mean that states will be lazily started when they are dereferenced: i.e. @my-state
they will also be all started by (mount/start)
, but this is an interesting property of cljc
mode, where the system can be just lazily started
not sure if you had a chance to read this: https://github.com/tolitius/mount/blob/0.1.9-SNAPSHOT/doc/clojurescript.md#managing-state-in-clojurescript
I might need to make it stand out a little more.. since it does not seem to be easy to find from the docs table of context
so the whole idea is, in cljs
:advanced
optimization wipes out all the namespaces, and renames all the vars, so we can no longer depend on a var being there to change it's value on start/stop
that would be called anywhere before a call to (mount/start), usually at the entry point of an app: in the -main, web handler, etc.
they don't have all the atom API (i.e. swap / reset!, etc..), but they have a @
(i.e. deref
)
(ns app.websockets
(:require [app.conf :refer [config]]
[app.audit-log :refer [audit log]])
(:require-macros [mount.core :refer [defstate]]))
;; ...
(defstate system-a :start (connect (get-in @config [:system-a :uri]))
:stop (disconnect system-a))
i.e. (a little internals): https://github.com/tolitius/mount/blob/0.1.9-SNAPSHOT/src/mount/core.cljc#L130-L132
the system would be started lazily, which means you might expect certain things to start on, say, page load, but they would not be, because nobody needed them yet
e.g. something needs to be loaded, but unless it is referenced anywhere or (mount/start)
was called it would not be (loaded)
that would depend on the use case (app), but I would not say longer, I would say.. it could start certain states at different time
if you need everything to start, and be very deterministic, you can call (mount/start)
Hadn't looked at (or had the need to) component yet and found the recent discussions around mount vs component very interesting. Mount seemed like the more light-weight solution.
sure, thanks for you feedback, keep it coming I am sure we can improve, especially on the cljs
side, so I would be very interested to know what works and what does not / could work better
I am experimenting a bit core.async, I needed a way to switch the way a put was handled for testing purposes and mount seemed good for that with it's start-with.
One optimization I think would be nice is to not reload the whole namespace but just the parts that changed. If I am not mistaken that is what figwheel does.
it's just a nice-to-have I guess, if I don't want a state to be reloaded I can change its namespace.
ah.. yea, that's a thought. the problem is stale references. for example you have a conn
state that holds a connection to a db
, when a namespace is recompiled, a new conn
reference is created
that is what I alluded to a little earlier: > it might make sense to make this behavior configurable: https://github.com/tolitius/mount#recompiling-namespaces-with-running-states >I feel like, in cljs, it could address both issues above, especially during full page reloads / sending large recompiled increments (by figwheel)
so you could potentially say something like
(defstate ^:dont-reload db :start (connect) :stop (disconnect))
might be good to have regardless.. i.e. (mount/don't-reload-on-recompile)
, but a better name
I see. Something that still got me stuck sometimes with figwheel and cursive is not understanding how to manage creation of go-blocks. If I were to take from a channel with a go block and change the go block and re-evaluate the old go block would also still grab off the channel until I reload the browser.
I haven't tried that yet with mount but maybe that clean-up logic will take care of that too?
you mean something like this: https://github.com/danboykis/shipper/blob/master/src/shipper/tools.clj#L8-L18 ?