Supervisord Dependent Startup
supervisord-dependent-startup is a plugin for Supervisor (a process control system) that allows services to start only after their specified dependent services have reached a 'RUNNING' state. It addresses a common challenge where services require others to be fully operational before they can reliably launch. The current version is 1.4.0, and releases are generally made to support new Supervisor versions or address specific use cases, leading to an infrequent but stable release cadence.
Common errors
-
ERROR (no such file) trying to run command python -m supervisord_dependent_startup.listener
cause The `command` path for the eventlistener in `supervisord.conf` is incorrect, or the Python environment where supervisord is running does not have `supervisord-dependent-startup` installed or accessible.fixVerify that `pip install supervisord-dependent-startup` was run in the correct environment. Ensure `python -m supervisord_dependent_startup.listener` executes correctly from the command line in the Supervisord's context. Use an absolute path to the Python executable if necessary (e.g., `/usr/bin/python3 -m supervisord_dependent_startup.listener`). -
Error: The program 'my_app' has a circular dependency.
cause Your `supervisord.conf` configuration defines a circular dependency chain between two or more programs (e.g., A depends on B, and B depends on A).fixReview your `dependencies` settings for all programs and redesign your startup order to eliminate circular references. One program must eventually be able to start without waiting for another in the cycle. -
Process 'my_app' did not start; dependencies 'db_service' did not reach RUNNING state.
cause One or more of the programs listed in the `dependencies` option for 'my_app' failed to transition to the `RUNNING` state, preventing 'my_app' from being started by the plugin.fixInspect the logs and status of the dependent services (`db_service` in this example) using `supervisorctl status` and `supervisorctl tail db_service` to identify why they are not reaching the `RUNNING` state.
Warnings
- gotcha This plugin requires Supervisor version 4.0.0 or higher. Using it with older Supervisor versions may lead to unexpected behavior or failure to load the event listener.
- gotcha The `dependencies` option relies on dependent processes reaching the `RUNNING` state. Processes stuck in `STARTING`, `BACKOFF`, or `STOPPED` states will prevent dependent programs from starting.
- gotcha When configuring `dependencies_stop_signal` on a program, it overrides Supervisord's `stopwaitsecs` for that specific program during the stop sequence. If not set, `stopwaitsecs` applies.
- breaking If migrating from the predecessor `ordered-startup-supervisord`, note that the configuration option for dependencies has changed from `ordered_startup_dependencies` to simply `dependencies`.
Install
-
pip install supervisord-dependent-startup
Imports
- listener
from supervisord_dependent_startup import listener
Quickstart
import os
# This Python quickstart demonstrates how the core listener module
# of 'supervisord-dependent-startup' can be referenced.
# IMPORTANT: This library is a Supervisord plugin and is NOT typically
# used by importing it directly into your application's Python code.
# It is executed by Supervisord itself.
try:
from supervisord_dependent_startup import listener
print(f"Successfully imported the Supervisord listener module: {listener.__name__}")
print(f"Path: {listener.__file__}")
print("\nThis module is designed to be run as an eventlistener via supervisord.conf:")
print("\n [eventlistener:dependent-startup]")
print(" command=python -m supervisord_dependent_startup.listener")
print(" events=PROCESS_STATE")
print("\nTo truly 'start' this plugin, you must configure Supervisord and launch Supervisord itself.")
except ImportError as e:
print(f"Error importing supervisord_dependent_startup.listener: {e}")
print("Please ensure 'pip install supervisord-dependent-startup' is complete.")
# A more practical quickstart would involve a supervisord.conf file, e.g.:
#
# [program:db_service]
# command=python /path/to/db_mock.py
# priority=100
#
# [program:my_app]
# command=python /path/to/my_app.py
# priority=200
# dependencies=db_service # <-- This is where the magic happens!
#
# For full setup, refer to the project's GitHub README.