Merge branch 'master' into 0.1.11
This commit is contained in:
commit
e9ba02b5a5
3 changed files with 33 additions and 14 deletions
28
README.md
28
README.md
|
|
@ -299,12 +299,12 @@ All of the above is much easier to understand by looking at examples:
|
||||||
|
|
||||||
This would start off from 5 states, even though the whole application may have many more states available. It would then exclude two states (i.e. `#'foo/c` and `#'bar/d`), then it will pass runtime arguments `{:a 42}`, and finally it will start the remaining three states: `#'foo/a`, `#'foo/b`, `#'baz/e`.
|
This would start off from 5 states, even though the whole application may have many more states available. It would then exclude two states (i.e. `#'foo/c` and `#'bar/d`), then it will pass runtime arguments `{:a 42}`, and finally it will start the remaining three states: `#'foo/a`, `#'foo/b`, `#'baz/e`.
|
||||||
|
|
||||||
You may notice that `only` takes a set, while `except` takes a vector in this example. This is done intentionally to demonstraate that both these functions can take any collection of states. `set` would make more sense for most cases though.
|
You may notice that `only` takes a set, while `except` takes a vector in this example. This is done intentionally to demonstrate that both these functions can take any collection of states. `set` would make more sense for most cases though.
|
||||||
|
|
||||||
Here is a more "involved" example:
|
Here is a more "involved" example:
|
||||||
|
|
||||||
```clojure
|
```clojure
|
||||||
(-> (only #{#'foo/a
|
(-> (only #{#'foo/a
|
||||||
#'foo/b
|
#'foo/b
|
||||||
#'foo/c
|
#'foo/c
|
||||||
#'bar/d
|
#'bar/d
|
||||||
|
|
@ -356,14 +356,14 @@ During testing it is often very useful to mock/stub certain states. For example
|
||||||
|
|
||||||
### Swapping States with Values
|
### Swapping States with Values
|
||||||
|
|
||||||
The `start-with` function takes values as substitues.
|
The `start-with` function takes values as substitutes.
|
||||||
|
|
||||||
Say we have a `send-sms` state:
|
Say we have a `send-sms` state:
|
||||||
|
|
||||||
```clojure
|
```clojure
|
||||||
(ns app.sms)
|
(ns app.sms)
|
||||||
;; ...
|
;; ...
|
||||||
(defstate send-sms :start (create-sms-sender
|
(defstate send-sms :start (create-sms-sender
|
||||||
(:sms config)))
|
(:sms config)))
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
@ -381,7 +381,7 @@ When running tests it would be great _not_ to send the real text messages, but r
|
||||||
|
|
||||||
### Swapping States with States
|
### Swapping States with States
|
||||||
|
|
||||||
The `start-with-states` function takes other states as substitues:
|
The `start-with-states` function takes other states as substitutes:
|
||||||
|
|
||||||
```clojure
|
```clojure
|
||||||
(mount/start-with-states {#'app.neo/db #'app.test/test-db
|
(mount/start-with-states {#'app.neo/db #'app.test/test-db
|
||||||
|
|
@ -459,23 +459,23 @@ Providing a `:stop` function _is_ optional, but in case a state needs to be clea
|
||||||
|
|
||||||
### :on-reload
|
### :on-reload
|
||||||
|
|
||||||
By default a state will be restarted on its redefenition or a namespace recompilation. However it is not always a desired behavior. Sometimes it's ok to have stale references during REPL sessions / development, other times all that is needed is not a "restart", but just a "stop".
|
By default a state will be restarted on its redefinition or a namespace recompilation. However it is not always a desired behavior. Sometimes it's ok to have stale references during REPL sessions / development, other times all that is needed is not a "restart", but just a "stop".
|
||||||
|
|
||||||
This behavior could be conrolled with an optional `:on-reload` meta attribute when defining a state.
|
This behavior could be controlled with an optional `:on-reload` meta attribute when defining a state.
|
||||||
|
|
||||||
In case _nothing_ needs to be done to a running state on reload / recompile / redef, set `:on-reload` to `:noop`:
|
In case _nothing_ needs to be done to a running state on reload / recompile / redef, set `:on-reload` to `:noop`:
|
||||||
|
|
||||||
```clojure
|
```clojure
|
||||||
(defstate ^{:on-reload :noop}
|
(defstate ^{:on-reload :noop}
|
||||||
mem-db :start (connect config)
|
mem-db :start (connect config)
|
||||||
:stop (disconnect mem-db))
|
:stop (disconnect mem-db))
|
||||||
```
|
```
|
||||||
|
|
||||||
When a running state needs to be just "stopped" on reload, set `:on-reload` to `:stop`:
|
When a running state needs to be just "stopped" on reload, set `:on-reload` to `:stop`:
|
||||||
|
|
||||||
```clojure
|
```clojure
|
||||||
(defstate ^{:on-reload :stop}
|
(defstate ^{:on-reload :stop}
|
||||||
mem-db :start (connect config)
|
mem-db :start (connect config)
|
||||||
:stop (disconnect mem-db))
|
:stop (disconnect mem-db))
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
@ -493,7 +493,7 @@ Mount will detect when a state was renamed/deleted from a namespace, and will do
|
||||||
Here is an example:
|
Here is an example:
|
||||||
|
|
||||||
```clojure
|
```clojure
|
||||||
dev=> (defstate won't-be-here-long :start (println "I am starting... ")
|
dev=> (defstate won't-be-here-long :start (println "I am starting... ")
|
||||||
:stop (println "I am stopping... "))
|
:stop (println "I am stopping... "))
|
||||||
#'dev/won't-be-here-long
|
#'dev/won't-be-here-long
|
||||||
dev=>
|
dev=>
|
||||||
|
|
@ -656,7 +656,7 @@ dev=> (find-orders conn "TSLA")
|
||||||
({:db/id 17592186045422, :order/symbol "TSLA", :order/bid 232.38M, :order/qty 100, :order/offer 232.43M})
|
({:db/id 17592186045422, :order/symbol "TSLA", :order/bid 232.38M, :order/qty 100, :order/offer 232.43M})
|
||||||
```
|
```
|
||||||
|
|
||||||
once something is changed in the code, or you just need to reload everything, do `(reset)`.
|
once something is changed in the code, or you just need to reload everything, do `(reset)`.
|
||||||
|
|
||||||
_note: a simple `(mount/stop)` / `(mount/start)` will also work, `(reset)` is for "convenience + ns refresh":_
|
_note: a simple `(mount/stop)` / `(mount/start)` will also work, `(reset)` is for "convenience + ns refresh":_
|
||||||
|
|
||||||
|
|
@ -705,7 +705,7 @@ dev=> (find-orders conn "TSLA")
|
||||||
|
|
||||||
### New York Stock Exchange Maintenance
|
### New York Stock Exchange Maintenance
|
||||||
|
|
||||||
Say we want to leave the exchange functioning, but would like to make sure that noone can hit it from the web. Easy, just stop the web server:
|
Say we want to leave the exchange functioning, but would like to make sure that no one can hit it from the web. Easy, just stop the web server:
|
||||||
|
|
||||||
```clojure
|
```clojure
|
||||||
dev=> (mount/stop #'app.www/nyse-app)
|
dev=> (mount/stop #'app.www/nyse-app)
|
||||||
|
|
|
||||||
BIN
doc/img/mount-logo.png
Normal file
BIN
doc/img/mount-logo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 99 KiB |
|
|
@ -301,6 +301,25 @@
|
||||||
(var-to-str to) :state))
|
(var-to-str to) :state))
|
||||||
states))
|
states))
|
||||||
|
|
||||||
|
;; restart on events
|
||||||
|
|
||||||
|
(defprotocol ChangeListener
|
||||||
|
(add-watcher [this ks watcher])
|
||||||
|
(on-change [this k]))
|
||||||
|
|
||||||
|
(deftype RestartListener [watchers]
|
||||||
|
ChangeListener
|
||||||
|
|
||||||
|
(add-watcher [_ ks state]
|
||||||
|
(doseq [k ks]
|
||||||
|
(swap! watchers update k #(conj % state))))
|
||||||
|
|
||||||
|
(on-change [_ k]
|
||||||
|
(let [states (@watchers k)]
|
||||||
|
(apply stop states)
|
||||||
|
(apply start states))))
|
||||||
|
|
||||||
|
|
||||||
;; explicit, not composable (subject to depreciate?)
|
;; explicit, not composable (subject to depreciate?)
|
||||||
|
|
||||||
(defn stop-except [& states]
|
(defn stop-except [& states]
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue