Resources: exchanging information between components
====================================================

Batou provides a well-defined, canonical way of passing information between
components at configuration time. Each component may publish ("provide") any
number of values, assigned to keys, and each component may query ("require")
values provided for a given key. Values may be any Python objects, including
components in turn.

Batou actively manages the process of providing and requiring values, aiming
to achieve a configuration order that allows all requirements to be fulfilled
with the correct sets of values provided throughout the deployment. This
relieves the user of figuring out in advance in what order components must be
configured to have each piece of shared information available when another
component needs it.

Batou will complain if a suitable order of configuration of all components
cannot be found, i.e. if the requirements create a dependency cycle between
components. It also catches some potential logical mistakes as it raises an
error if a value is provided for a key that is never required.


provide/require/require_one
---------------------------

The component API contains methods for providing and requiring a key,
including a convenience variant for requiring a key that is expected to have
exactly one value provided.

.. py:class:: Component

   .. py:attribute:: provide(key, value)

      Publish a Python ``value`` to be assigned to the ``key``. The assignment
      is remembered to originate with the root component currently being
      configured.

      Batou keeps track of which components require values for a particular
      key. Whenever a component provides a new value during configuration, any
      other components known to be interested are scheduled for
      re-configuration.

   .. py:attribute:: require(key, host=None)

      Query any values assigned to the ``key`` by any component throughout the
      deployment. If a ``host`` is given, the result will be restricted to
      values provided by components on the same host as the component stating
      the requirement.

      Returns a (possibly empty) sequence of values.

   .. py:attribute:: require_one(key, host=None)

      Analogous to ``require`` but assumes that the result contains exactly
      one value. Errors are raised if no value or more than one value is found
      for the ``key`` (and ``host```if given).

      Returns exactly one Python value (not contained in a sequence).


hook components (TBD)
---------------------

