Dec 10, 2016 • Arnout Roemers
In a previous blog post the
mount-lite library was introduced.
In short, it explained why I like the premise of
mount, and what moved me to create a spin-off.
This time I want to talk about what has changed between the
0.9.x versions of that blog post and the recently released
0.9.x versions, the
mount-lite library used to be bigger.
It was different from the original
mount, with features such as a composable data-driven API, bindings, parallel starting and stopping, starting and stopping “up to” a particular state, automatic dependency graphs, and cleaner substitutions.
In the mean time, the original
mount has dropped unnecessary features, has also created a composable API, and is improving substitutions as well.
It is good to see this, as
mount is more popular, and all kudos should still go to the original author of course.
2.0.0 version introduces the ability to run multiple systems of states simultaneously.
In other words, a single
defstate can be started multiple times in different contexts.
One major reason for introducing this feature, is to be able to run test suites in parallel.
As this is a breaking change, it was a good opportunity to get rid of the excess, based on experience in several larger projects.
With the new version,
mount-lite still has it’s own take and feature set with respect to the original
In short, apart from the multiple-instances feature, the following has changed:
derefwhen using a started state. This enables the multiple-instances feature.
bindingsfeature and the
parallelstart/stop feature have been removed, as those were rarely used and only added complexity.
exceptfeatures have been removed as well, as the
up-tofeature is all you (should) need. The unique
up-tofeature is now standard. The
exceptfeatures could be harmful - they could leave your system in a bad state - and they rarely used. They could get your system in a bad state.
startfunction. This means that you don’t have to change anything within the
(start)expression or its immediate vicinity.
Because of these feature changes, the API has been trimmed down to a simple mininium, not requiring it to be composable or data-driven.
In my experience, most
mount-lite users were not the power user I expected them to be.
So many options the data-driven composabe API offered, were rarely used.
The new API comprises of only the bare minimum of features that are actually used.
The API has become simpler because of this, and therefore easier to learn and understand.
The API now comes down to:
(defstate ...), only having a
(stop), or starting and stopping up to a certain state var using
(with-substitutes [#'my-state (state ...)] ...)macro, which can be nested.
If you can’t live without the removed features, know that you can add some of them yourself by using the extension point mount-lite now offers. Otherwise, keep using the
0.9.x version, as it will still be supported.
But how do you use that new feature, having multiple systems of states simultateously living next to each other?
mount-lite library does this in a transparent way, i.e. there is no difference in how the library is used, whether this feature is utilized or not.
This is in contrast with the yurt library from the original
When you just
(start) your states, you start them in the default context.
The entire application accesses those states as normal.
By wrapping your
(start) with the
with-session macro, the thread that is then spawned - and all of its subthreads - will use a new system of states.
The states themselves and the code that uses them does not change a bit.
The states in that session are automatically stopped when the thread is done.
The example below shows how we use the
with-session macro to spin up a new thread and execute its body.
The example starts up two systems of states this way, and the use of
CountDownLatches ensures the systems run concurrently when printing the value of the
The printed output is shown below.
As you can see, two different values are printed, and subthreads use running states from parent threads.
The order in which
2 are printed, or the order in which
sub stopping are printed, might of course be swapped.
mount-lite library now truly fulfills the “lite” part. With version
2.0.0 it has gone back to the core of its functionality, based on real world projects and user experience. I hope you like it. The documentation has been updated to reflect this new version, including a migration guide. If you have questions or suggestions, I’d love to hear them, for example on twitter or the #mount channel on Clojurians Slack.
As always, have fun!