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-0.1.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-0.1.0-py3-none-any.whl (22.1 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: crazy_workers-0.1.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-0.1.0.tar.gz
Algorithm Hash digest
SHA256 80260f6f30c6bc552ec518b10b1e30059a1d56e5848ed034d1db1e51520f1520
MD5 a82b01f23dcdb9b1e81243efc6690555
BLAKE2b-256 cb50c75a7e47c03279a59c1469f3575e85f29a6e4dc6dfe1fb1adb7148625f08

See more details on using hashes here.

Provenance

The following attestation bundles were made for crazy_workers-0.1.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-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: crazy_workers-0.1.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-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 bef4f76eee8a3d4c7f9b8eec7340a9bc78a6824aa29eb8ec49b25f3e3dbdd5ca
MD5 c735d39b19286f3b702c8095c3bab1b4
BLAKE2b-256 7153f86b72da95a6610349764143ae4dd1f0563e3127c18d3dac81c3fafa9369

See more details on using hashes here.

Provenance

The following attestation bundles were made for crazy_workers-0.1.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