[spootnik/maniflow "0.1.4"]
The manifold.lifecycle
namespace provides a lightweight take on a
mechanism similar to interceptors.
A lifecycle is nothing more than a collection of handlers through which a value is passed.
In essence:
@(run 0 [inc inc inc])
Is thus directly equivalent to:
(-> 0 inc inc inc)
As shown above, each step in a lifecycle is a handler to run on a value. Steps can be provided in several forms, all coerced to a map.
{:manifold.lifecycle/id :doubler
:manifold.lifecycle/handler (fn [input] (* input 2))
:manifold.lifecycle/context? false
:manifold.lifecycle/guard (fn [context] ...)}
When a step is a plain function, as in (run 0 [inc])
, the
resulting map will be of the following shape:
{:manifold.lifecycle/id :step12345
:manifold.lifecycle/handler inc
:manifold.lifecycle/context? false}
If the function is provided as a var, the qualified name of the var
is used as the id, so for (run 0 [#'inc])
we would have instead:
{:manifold.lifecycle/id :clojure.core/inc
:manifold.lifecycle/handler inc
:manifold.lifecycle/context? false}
There are cases where accessing the context directly could be useful,
in this case :manifold.lifecycle/context?
should be set to true
in the step definition:
(defn determine-deserialize
[{:manifold.lifecycle/keys [input] :as context}]
(cond-> context
(= :post (:request-method input))
(assoc context ::need-deserialize? true)))
{:manifold.lifecycle/id :determine-deserialize
:manifold.lifecycle/handler determine-deserialize
:manifold.lifecycle/context? true}
Based on the current state of processing, it might be useful to guard execution of a step against a predicate, keeping with the last example:
{:manifold.lifecycle/id :deserialize
:manifold.lifecycle/handler deserialize
:manifold.lifecycle/context? false
:manifold.lifecycle/guard ::need-deserialize?}
step
The manifold.lifecycle/step
function is provided to build steps
easily, the above can thus be rewritten:
(step :determine-deserialize determine-deserialize :context? true)
(step :handler run-handler)
(step :deserialize deserialize :guard :need-deserialize?)
When running a lifecycle, an options map can be passed in to further modify the behavior:
{:manifold.lifecycle/clock clock-implementation
:manifold.lifecycle/context? false}
The clock options is an implementations of spootnik.clock.Clock
from
commons used for timing steps in
the context map. context?
defaults to false and determines whether
the deferred that run
yields the result or the context map.
There are intentionally no facilities to interact with the sequence of
steps in this library. Exceptions thrown will break the sequence of
steps, users of the library are encouraged to use
manifold.deferred/catch
to handle errors raised during execution.
All errors contain the underlying thrown exception as a cause and
contain the last known context in their ex-data
(-> (d/run 0 [inc #(d/future (/ % 0)) inc])
(d/catch (fn [e]
(type (.getCause e)) ;; ArithmeticException
(:manifold.lifecycle/context (ex-data e)) ;; last context)))
Can you improve this documentation?Edit on GitHub
cljdoc is a website building & hosting documentation for Clojure/Script libraries
× close