Note: this re-post is due to an error I made earlier today. I've gutted
out a bunch of stuff as well. My apologies for the duplication.
On 4/28/2015 11:34 AM, Laurent Bercot wrote:
I'm also interested in Avery's experience with dependency handling.
Hm. Today isn't the best day to write this (having been up since 4am)
but I'll try to digest all the little bits and pieces into something.
Here we go...
First, I will qualify a few things. The project's scope is, compared to
a lot of the discussion on the mailing list, very narrow. There are
several goals but the primary thrust of the project is to create a
generic, universal set of service definitions that could be plugged into
many init, distribution, and supervision framework arrangements. That's
a tall order in itself, but there are ways around a lot of this. So
while the next three paragraphs are off-topic, they are there to address
those three concerns mentioned.
With regard to init work, I don't touch it. Trying to describe a proper
init sequence is already beyond the scope of the project. I'm leaving
that to other implementers.
With regard to distributions, well, I'm trying to make it as generic as
possible. Development is done on a Debian 7 box but I have made efforts
to avoid any Debian-isms in the actual project itself. In theory, you
should be able to use the scripts on any distribution.
With regard to the supervision programs used, the difference in command
names have been abstracted away. I'm not entirely wild about how it is
currently done, but creating definitions is a higher priority than
revisiting this at the moment. In the future, I will probably
restructure it.
~ ~ ~ ~ ~ ~ ~ ~
What
---
The dependency handling in supervision-scripts is meant to be used in
installations that don't have access to it. Put another way, it's a
"Poor Man's Solution" to the problem and functions as a convenience.
The feature is turned off by default, and this will cause any service
definition that requires other services to run-loop repeatedly until
someone starts them manually. This could be said to be the default
behavior of most installations that don't have dependency handling, so
I'm not introducing a disruptive behavior with this feature.
Why
---
I could have hard-coded many of the dependencies into the various run
scripts, but this would have created a number of problems for other areas.
1. Hard-coding prevents switching from shell to execline in the future,
by necessitating a re-write. There will be an estimated 1,000+ scripts
when the project is complete, so this is a major concern.
2. We are already using the filesystem as an ad-hoc database, so it
makes sense to continue with this concept. The dependencies should be
stored on the filesystem and not inside of the script.
With this in mind, I picked sv/(service)/needs as a directory to hold
the definitions to be used. Because I can't envision what every init
and future dependency management framework would look like, I'll simply
make it as generic as I can, leaving things as open as possible to
additional changes.A side note: it is by fortuitous circumstance
that anopa uses a ./needs directory that has the same functionality and
behavior. I use soft links "just because". Anopa uses named files.
The net effect is the same.
Each dependency is simply a named soft link that points to a service
that needs to be started, typically something like
"sv/(service)/needs/foobar points to /service/foobar". In this case, a
soft link is made with the name of the service, pointing to the service
definition in /service. This also allows me to ensure that the
dependency is actually available, and not just assume that it is there.
A single rule determines what goes into ./needs, "you can only have the
names of other services that are explicitly needed". You can say "foo
needs baz" and "baz needs bar" but NEVER would you say "foo needs baz,
foo needs bar". This is intentional because it's not the job of the
starting service to handle the entire chain. It simplifies the list of
dependencies because a service will only worry about its immediate
needs, and not the needs of dependent services it launches. It also has
the desirable property of making dependency chains self-organizing,
which is an important decision with hundreds of services having
potentially hundreds of dependencies. Setup is straightforward and you
can easily extend a service need by adding one soft link to the new
dependency. This also fits with my current use of a single launch
script; I don't have to change the script, just the parameters that the
script uses. The new soft link becomes just another parameter. You
could call this "peer-level dependency resolution" if you like.
How
---
Enabling this behavior requires that you set sv/.env/NEEDS_ENABLED to
the single character "1". It is normally set to "0". With the setting
disabled (