Rework how Knobs are handled
danidiaz opened this issue · comments
Knob
s are controls associated to some components which allow controlling the component from an HTTP endpoint, kind of like what the "actuator" framework does for Spring Boot.
Right now, if we want to add a component with a Knob
, we have to register it in two places: in the main composition root, and in the Servant "runner" component.
This is annoying, it would be better to specify it in only one place. A further annoyance is that we need to add two coomponents to the composition root: the component-with-knob and the bare component.
The following solution is implemented in c9ce51a:
- An alternative to the
Constructor
type has been added calledAccumConstructor
. This latter type embodies the notion of constructors that, besides reading from the final environment and producing a record-of-functions of a specific type, also read and produce a monoidal accumulator value. - In our case, we use a map of
Knob
values as the accumulator. - The logger component produces a
KnobMap
value containing a single entry, theKnob
for the logger. - The
KnobServer
component reads the accumulatedKnobMap
and produces a Servant server for querying and setting all knobs (although currently there's only the loggerKnob
.)
With these changes, we don't need to update in two places whenever we add a component accompanied by a Knob
. It's enough to update the composition root!