taxonomy of dependencies

From: Wayne Marshall <wcm_at_b0llix.net>
Date: Tue, 28 Apr 2015 12:20:33 -0700

Quite a lot of clock-cycles are being devoted to the discussion of
dependencies among services.

I would like to suggest that not all dependencies are created equal.
That is, some (if not most) dependencies are really of no practical
consequence -- and we don't need to worry about them in terms of
sequentializing service start-up. Other dependencies (and their number
is fewer) may in fact require our attention through simple handling
within the runscript.

First a preliminary statement: service dependencies are of a different
nature than, say, build dependencies or package installation
dependencies. Efforts to use these paradigms for ordering service
start-up will generally lead to unnecessary complexity. Unnecessary
complexity is a Bad Thing. As the system becomes complex, it becomes
opaque, confusing, prone to error, hard to troubleshoot, and difficult
to administer. Then you are right back to the problems of, say,
sysvinit or systemd from which you are trying to escape.

To the extent that we can recognize and categorize service
dependencies, we may simplify our runscripts considerably. What follows
below is an effort (admittedly a first-cut) to describe a "taxonomy" of
service dependencies.

0) No dependency. A service has no functional dependency on any other
service. (Mentioned here for completeness). Nothing to worry about.

1) Logical only dependency. A service has only a logical dependency on
another service; in terms of functional behavior however, arranging for
ordered start-up is unnecessary. There is no pathological functional
behavior associated with starting in parallel or in any particular
order. Again, nothing to worry about.

2) Functional dependency - soft. A service has a functional dependency
on another service, as in, it cannot perform it's task without the other
service running. Yet there is no pathological functional behavior
exhibited by the service in cases where the dependency is not running.
That is, the service simply defers connections or reports not ready
until the dependency is running. Once again, still nothing for us to
worry about in terms of special handling within runscripts, as the
services may be started in any order.

3) Functional dependency - medium. A service has a functional
dependency on another service, and fails to start if the dependency is
not running. This is actually quite a nice arrangement, because the
service itself is testing for its dependency without any additional
effort on our part. Under a supervision framework, failure of a
service starting is absolutely ok. (Many novices fail to grasp the
elegance of this essential feature.) The system will automatically
attempt to restart the failed service at intervals until the dependency
is met. Yet again, nothing to worry about in our runscripts.

4) Functional dependency - hard. A service has a functional dependency
on another service, yet will start and run no error without the
dependency, and doing so results in some kind of pathological
behavior. The pathological behavior may expose the system to security
vulnerability, resource blockage, or provide users with erroneous data
or bad results. Now -- finally -- this is a case we have to worry
about. The runscripts must be designed to explicitly require the
dependency before starting the service.

When working with dependencies in this last category #4, all we have to
to do is to make runscripts that effectively turn them into category #3.
That is, we simply want to immediately fail any service whose required
dependency is not running.

An example of dependency handling under the perp system is illustrated
in the perpok(8) manual page in the EXAMPLES section:

http://b0llix.net/perp/site.cgi?page=perpok.8

Alternatively, one may write purpose-specific dependency checking
utilities, such as with ncat, etc., to make sure that the dependency is
not only running, but serving a set of expected results.

Note also that in no case is it necessary for a service runscript to try
starting dependencies itself -- this is all left to the supervisor.
All the runscript needs for category #4 dependencies is to check for
the dependency, and fail immediately if that check fails. Simplissimo.

--
Wayne
http://b0llix.net/perp/
Received on Tue Apr 28 2015 - 19:20:33 UTC

This archive was generated by hypermail 2.3.0 : Sun May 09 2021 - 19:44:19 UTC