{"id":14487,"library":"circus","title":"Circus Process & Socket Manager","description":"Circus is a robust Python program designed to run, monitor, and manage multiple processes and sockets. It provides a flexible way to supervise long-running services, akin to tools like Supervisor, but with a focus on programmatic control and extensibility. The current version is 0.19.0. Releases are somewhat irregular, often tied to Python version support or dependency updates.","status":"active","version":"0.19.0","language":"en","source_language":"en","source_url":"https://github.com/circus-tent/circus","tags":["process manager","daemon","supervisor","async","watcher","process supervision"],"install":[{"cmd":"pip install circus","lang":"bash","label":"Install latest version"}],"dependencies":[{"reason":"Process monitoring and management","package":"psutil","optional":false},{"reason":"Inter-process communication and control","package":"pyzmq","optional":false},{"reason":"Asynchronous event loop for I/O and networking","package":"tornado","optional":false}],"imports":[{"symbol":"Arbiter","correct":"from circus.arbiter import Arbiter"},{"symbol":"Watcher","correct":"from circus.watcher import Watcher"},{"symbol":"CircusClient","correct":"from circus.client import CircusClient"}],"quickstart":{"code":"from circus.watcher import Watcher\nfrom circus.arbiter import Arbiter\nimport time\nimport sys\n\n# Define a simple command to run\n# Using sys.executable ensures the current Python environment's interpreter is used.\ncommand = f\"{sys.executable} -c \\\"import time; print('Hello from Circus!'); time.sleep(2); print('Process exiting.')\\\"\"\n\n# Create a watcher for our process\n# 'stop_signal' 15 (SIGTERM) is a common graceful shutdown signal\nwatcher = Watcher(name=\"my_test_process\", cmd=command, numprocesses=1, stop_signal=15)\n\n# Create an arbiter and register the watcher\narbiter = Arbiter([watcher])\n\nprint(\"Starting Circus Arbiter...\")\ntry:\n    # Start the arbiter, which will launch and manage the watcher's processes\n    arbiter.start()\n    print(\"Arbiter started. Processes are running. Press Ctrl+C to stop.\")\n    # Keep the main thread alive to allow the arbiter to run in the background\n    while True:\n        time.sleep(1)\nexcept KeyboardInterrupt:\n    print(\"\\nCtrl+C detected. Stopping Arbiter...\")\n    # Cleanly stop the arbiter and its managed processes\n    arbiter.stop()\n    print(\"Arbiter stopped. Exiting.\")\nexcept Exception as e:\n    print(f\"An error occurred: {e}\")\n    arbiter.stop()\n    sys.exit(1)\n","lang":"python","description":"This quickstart demonstrates how to programmatically define a watcher for a simple Python script and manage it using the Circus Arbiter. Run this script, and it will start a child process that prints messages every 2 seconds until the Arbiter is stopped via Ctrl+C."},"warnings":[{"fix":"Upgrade to Python 3.7 or newer, or use an older Circus version compatible with your Python environment.","message":"Circus versions 0.17.0+ dropped support for Python 2.7, 3.3, and 3.4. Version 0.16.0+ dropped support for Python 2.6 and 3.3. Ensure your Python environment meets the `>=3.7` requirement for recent versions.","severity":"breaking","affected_versions":"<0.17.0"},{"fix":"Ensure `tornado` is `>=5.0` and `pyzmq` is `>=17.0` for Circus 0.17.0+. Use `pip install --upgrade circus` to automatically resolve the correct dependency versions.","message":"Dependency requirements for Tornado and PyZMQ changed significantly. Circus 0.15.0 explicitly forbid Tornado >= 5 and PyZMQ >= 17, while 0.16.0+ requires PyZMQ >= 17 and 0.17.0+ requires Tornado >= 5. This can lead to dependency conflicts or runtime errors if versions are mismatched.","severity":"breaking","affected_versions":"0.15.0-0.17.0"},{"fix":"Review your `circus.ini` files for interpolation directives. If issues arise, consider rewriting parts of your configuration or escaping special characters that might be misinterpreted by `RawConfigParser`.","message":"Starting with version 0.17.0, Circus uses `RawConfigParser` instead of `ConfigParser` for its `.ini` configuration files. If your configuration heavily relies on `ConfigParser`'s interpolation features (e.g., `${section:option}`), these might no longer work as expected and could lead to parsing errors.","severity":"gotcha","affected_versions":">=0.17.0"},{"fix":"Update any shell scripts or automation that executes `circusctl` to correctly interpret non-zero exit codes as indications of command failure.","message":"From version 0.15.0, the `circusctl` command-line utility returns a non-zero exit code when a command fails. This is a behavioral change from previous versions which might have always returned zero. Scripts relying on `circusctl`'s exit code for success/failure detection will need to be updated.","severity":"gotcha","affected_versions":">=0.15.0"}],"env_vars":null,"last_verified":"2026-04-16T00:00:00.000Z","next_check":"2026-07-15T00:00:00.000Z","problems":[{"fix":"Run `pip install circus` to install the library.","cause":"The `circus` library is not installed or not available in the current Python environment.","error":"ImportError: No module named 'circus.arbiter'"},{"fix":"Upgrade your Tornado installation: `pip install --upgrade tornado` or ensure `pip install circus` resolves compatible versions.","cause":"Your installed `tornado` package is older than the minimum version required by Circus (typically >=5.0 for recent Circus versions).","error":"circusd: error: The current Tornado version (X.Y) is too old."},{"fix":"Check your `circus.ini` file for correct syntax, missing sections/options, or unintended interpolation. Ensure options are explicitly defined.","cause":"Configuration file parsing issue, potentially due to the `RawConfigParser` change in Circus 0.17.0+, or malformed INI syntax.","error":"ConfigParser.NoOptionError: No option '...' in section: '...'"},{"fix":"Examine the error message from `circusctl` for the specific failure reason. Update calling scripts to handle non-zero exit codes from `circusctl`.","cause":"A `circusctl` command failed, and the utility returned a non-zero exit code, potentially breaking scripts that expect a zero exit code on all `circusctl` operations.","error":"circusctl: error: Command 'mycommand' failed (status: error_message_here)"}],"ecosystem":"pypi"}