Skip to main content

A Python library for managing background worker processes with persistent state, automatic recovery, and a CLI.

Project description

Crazy Workers

A Python library for managing background worker processes with persistent state, automatic crash recovery, and a built-in CLI.

Python 3.10+ License: MIT

Features

  • Persistent State — SQLite database tracks worker status, PIDs, and parameters across restarts.
  • Process Management — Start, stop, and monitor background Python scripts as independent OS processes.
  • Automatic Recovery — Detects crashed workers and restarts them on application boot.
  • Child Process Control — On stop, terminates unmanaged subprocesses while preserving independently-managed nested workers.
  • CLI Interface — Manage workers from the terminal with interactive prompts and auto-discovery (see CLI.md).
  • Security — Built-in protection against path traversal in worker type and key names.
  • Observability — Per-worker file logging; all service files (DB, lock, logs) live in a .service/ folder inside your workers directory.
  • Zombie Protection — Distinguishes active processes from zombies using psutil.
  • Gunicorn-safe — File-based lock prevents concurrent recovery runs across multiple workers.

Installation

pip install crazy-workers

Or from source:

git clone https://github.com/Vanni-broUser/crazy-workers
cd crazy-workers
pip install .

Quick Start

1. Create a worker script

# workers/my_worker.py
import json, sys, time

params = json.loads(sys.argv[1]) if len(sys.argv) > 1 else {}
duration = params.get('duration', 60)

for _ in range(duration):
    time.sleep(1)

2. Manage it from Python

from crazy_workers import WorkerManager

manager = WorkerManager('workers')

# Start
success, result = manager.start_worker(
    'my_worker',
    worker_key='job_1',
    parameters={'duration': 30},
)
print(result['pid'])   # OS process ID
print(result['status'])  # 'RUNNING'

# List
for w in manager.list_workers():
    print(w['worker_key'], w['status'])

# Stop
manager.stop_worker('job_1')

# Recover crashed workers (call on app startup)
restarted = manager.recover_workers()

manager.dispose()  # releases DB connection; does NOT kill workers

3. Or from the CLI

crazy-workers list
crazy-workers start my_worker --key job_1 --params '{"duration": 30}'
crazy-workers stop job_1
crazy-workers restore

See CLI.md for full CLI documentation.

API Reference

WorkerManager(workers_dir, create_dir=True)

Parameter Type Default Description
workers_dir str 'workers' Directory containing worker .py scripts
create_dir bool True Create workers_dir and .service/ if they don't exist

start_worker(worker_type, worker_key=None, parameters=None, env=None)

Parameter Type Default Description
worker_type str Filename (without .py) of the worker script
worker_key str worker_type Unique identifier; allows multiple instances of the same type
parameters dict {} JSON-serializable dict passed as sys.argv[1] to the worker
env dict None Extra environment variables injected into the worker process

Returns (bool, dict | str)(True, worker_dict) on success, (False, error_message) on failure.

stop_worker(worker_key)

Gracefully terminates the worker (SIGTERM → SIGKILL after timeout). Returns (bool, str).

list_workers()

Returns a list of worker dicts including RUNNING, STOPPED, CRASHED, and NEVER_STARTED (filesystem-discovered) workers.

recover_workers()

Restarts any worker whose DB status is RUNNING but whose process is dead. Uses a file lock to prevent concurrent recovery. Returns a list of restarted keys.

dispose()

Closes the database connection and clears internal process references. Does not kill background workers — they continue running independently.

Worker Script Contract

A worker receives its parameters as a JSON string in sys.argv[1]:

import json, sys

params = json.loads(sys.argv[1]) if len(sys.argv) > 1 else {}
# ... do work ...

Project Structure

crazy_workers/       # Library package
  core/              # WorkerManager, process engine, recovery lock
  cli/               # CLI entry point, commands, discovery
  database/          # SQLAlchemy schema and SQLite storage
example_app/         # Flask demo application
  app.py
  workers/           # Example worker scripts
tests/
  core/              # Unit tests for core modules
  cli/               # Unit tests for CLI modules
  database/          # Unit tests for storage layer
  integration/       # Full-stack integration tests (real processes)
  app/               # Tests for the example Flask app

Flask Integration

from crazy_workers import WorkerManager

def create_app():
    app = Flask(__name__)
    manager = WorkerManager('workers')

    @app.route('/workers/start', methods=['POST'])
    def start():
        data = request.json
        success, result = manager.start_worker(
            data['worker_type'],
            worker_key=data.get('worker_key'),
            parameters=data.get('parameters', {}),
        )
        return (jsonify(result), 200) if success else (jsonify({'error': result}), 400)

    manager.recover_workers()  # restart any crashed workers on boot
    return app

See example_app/app.py for a complete example.

Gunicorn / Multi-Process Servers

When using a pre-fork server like Gunicorn:

  • Recovery is atomic — a file lock (.service/workers.db.recovery.lock) ensures recover_workers() runs once even when multiple workers boot simultaneously.
  • Workers outlive their parent — if a Gunicorn worker is recycled, background processes keep running. The next recovery cycle re-attaches or restarts them.

Development

Setup

git clone https://github.com/Vanni-broUser/crazy-workers
cd crazy-workers
pip install -e .[dev]

Commands

# Lint and format
ruff check . --fix && ruff format .

# Run tests
pytest

# Run tests with coverage
coverage run -m pytest && coverage report

Standards

See AI.md for the full coding and testing standards used in this project.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

crazy_workers-1.0.0.tar.gz (18.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

crazy_workers-1.0.0-py3-none-any.whl (22.1 kB view details)

Uploaded Python 3

File details

Details for the file crazy_workers-1.0.0.tar.gz.

File metadata

  • Download URL: crazy_workers-1.0.0.tar.gz
  • Upload date:
  • Size: 18.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for crazy_workers-1.0.0.tar.gz
Algorithm Hash digest
SHA256 18b08a0094853958214af7b339adb98662179332e064107bb996275fbeba9f06
MD5 dbca72c652f40232d2192a215c49a432
BLAKE2b-256 5e91711adc19365ac10e54fc95f7691980de912971dde3bf187d16bab249a56d

See more details on using hashes here.

Provenance

The following attestation bundles were made for crazy_workers-1.0.0.tar.gz:

Publisher: ci.yml on Vanni-broUser/crazy-workers

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file crazy_workers-1.0.0-py3-none-any.whl.

File metadata

  • Download URL: crazy_workers-1.0.0-py3-none-any.whl
  • Upload date:
  • Size: 22.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for crazy_workers-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 87af1dc38c7bd2a5659193fb935ed249d407628bd12f1a21fb6312c5a5abee74
MD5 71e0249d4f16ed49b07e7c769d2eacdd
BLAKE2b-256 974660041d622f718d91f8c6367dba4e66e478a131b1fa2afa86ba802878d34a

See more details on using hashes here.

Provenance

The following attestation bundles were made for crazy_workers-1.0.0-py3-none-any.whl:

Publisher: ci.yml on Vanni-broUser/crazy-workers

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page