Custom Signals
donut.system uses the terms “signal” and “signal handling” because component behavior is extensible. Other component libraries use the term lifecycle, which doesn’t convey the sense of extensibility that’s possible with donut.system.
Out of the box, donut.system recognizes ::ds/start, ::ds/stop,
::ds/suspend, ::ds/resume, and ::ds/status signals, but it’s possible to
handle arbitrary signals – say, :your.app/validate or :your.app/status. To
do that, you just need to add a little configuration to your system:
(def system
{::ds/defs {;; components go here
}
::ds/signals {:your.app/status {:order :topsort}
:your.app/validate {:order :reverse-topsort}}})::ds/signals is a map where keys are signal names and values are configuration
maps. The configuration keys are:
:order values can be :topsort or :reverse-topsort. This specifies the
order that components’ signal handlers should be called. :topsort means that
if Component A refers to Component B, then Component A’s handler will be called
first; reverse is, well, the reverse.
:returns-instance? this determines whether the return value of the signal
handler should be used to update the system’s instances, under ::ds/instances.
You would set this to false if want to use the return value of the signal for
some purpose other than updating the instance. The ::ds/status signal is set
up this way because its purpose is to return status information.
The map you specify under ::ds/signals will get merged with your system’s
default signal map, which is:
(def default-signals
"which graph sort order to follow to apply signal, and where to put result"
{::start {:order :reverse-topsort
:returns-instance? true}
::stop {:order :topsort
:returns-instance? true}
::suspend {:order :topsort
:returns-instance? true}
::resume {:order :reverse-topsort
:returns-instance? true}
::status {:order :reverse-topsort}})