I wouldn't do dependency resolution at runtime at all on servers. I would do it at install time and generate a static set of ordered steps. This has a few desirable effects:
* It ensures changes can be audited, observed and tracked (or caught and prohibited). Explicit change control points are key.
* It provides an interface and an option, divorcing the dependency tool from the system which invokes the ordering
* Ordered sequential steps takes longer, but adds determinism. It enormously simplifies the startup process, including auditing where things go wrong in logs after the fact. For servers, this is far more important than lower start times.
Most systems end up with a distro/systemd controlled base and a custom application on top. Often there's all kinds of special harness around the application, far beyond what can be fit into systemd. So there's always necessary duplication and struggles around interfacing different kinds of systems.
For custom applications, I tend to advise that the development team first come up with the success criteria for their app. What conditions would they page on, and what runtime dependencies does their app need? (Databases, up to date feeds, kill switches/feature flags, etc). I suggest that they re-use their monitoring code to also control orchestration of service startup. For example, not starting a front-end app unless a connection check to a backend SQL server passes. In these cases, the orchestration may be significantly more complex than what can be performed inside of systemd -- and this is part of why a clean and extensible interface is so important.
* It ensures changes can be audited, observed and tracked (or caught and prohibited). Explicit change control points are key.
* It provides an interface and an option, divorcing the dependency tool from the system which invokes the ordering
* Ordered sequential steps takes longer, but adds determinism. It enormously simplifies the startup process, including auditing where things go wrong in logs after the fact. For servers, this is far more important than lower start times.
Most systems end up with a distro/systemd controlled base and a custom application on top. Often there's all kinds of special harness around the application, far beyond what can be fit into systemd. So there's always necessary duplication and struggles around interfacing different kinds of systems.
For custom applications, I tend to advise that the development team first come up with the success criteria for their app. What conditions would they page on, and what runtime dependencies does their app need? (Databases, up to date feeds, kill switches/feature flags, etc). I suggest that they re-use their monitoring code to also control orchestration of service startup. For example, not starting a front-end app unless a connection check to a backend SQL server passes. In these cases, the orchestration may be significantly more complex than what can be performed inside of systemd -- and this is part of why a clean and extensible interface is so important.