Overview - Nuvom
Author: Nahom Zewdu
Description: Lightweight, plugin-first Python task queue — no Redis required.

Skip to content

# Plugin System

Nuvom v0.9 introduced first-class plugin support — allowing developers to register their own backends, extensions, and instrumentation layers with clean lifecycle management.

## 🔌 What is a Plugin?

A plugin is a Python class that implements the `Plugin` protocol, defining:

- `name`: Unique plugin name
- `provides`: What kind of capability it offers (e.g. `queue_backend`, `monitoring`)
- `start(settings: dict)`: Initialization logic
- `stop()`: Cleanup logic on shutdown

## 📁 File Layout

Plugins can live inside your project or in external libraries. Common layout:

    my_project/
    ├── plugins/
    │   ├── my_plugin.py       # Your plugin logic
    │   └── __init__.py
    └── .nuvom_plugins.toml    # Plugin registration
    ````

    ---

    ## 🧱 Plugin Example: Custom Queue Backend

    ```python
    # plugins/my_queue.py
    from nuvom.queue_backends.base import BaseJobQueue
    from nuvom.plugins.contracts import Plugin

    class MyQueue(BaseJobQueue):
        def enqueue(self, job): ...
        def dequeue(self, timeout=None): ...
        def pop_batch(self, n): ...
        def qsize(self): ...
        def clear(self): ...

    class MyPlugin(Plugin):
        name = "my_queue"
        provides = ["queue_backend"]

        def start(self, settings):
            from nuvom.plugins.registry import register_queue_backend
            register_queue_backend("my_custom_queue", MyQueue)

        def stop(self):
            pass

Then register in `.nuvom_plugins.toml`:

    [plugins]
    queue_backend = ["plugins.my_queue:MyPlugin"]

## 🗃 Plugin Registry

Nuvom loads plugins at worker startup (not during CLI commands).

Each plugin is discovered from `.nuvom_plugins.toml`, instantiated, and injected with runtime settings.

To test plugin loading:

    nuvom plugin test
    nuvom plugin list
    nuvom plugin inspect my_queue

## 🛠 Plugin Lifecycle

Each plugin receives a `start(settings)` call when the worker starts.

Example use cases:

- Registering new backends
- Spawning monitoring threads
- Configuring metrics exporters
- Connecting to databases

On shutdown (`CTRL+C`, SIGINT), plugins receive a `stop()` call to clean up.

## 🧪 Plugin Types

Provides | Purpose
--- | ---
`queue_backend` | Add a new job queue implementation
`result_backend` | Add a result/error store
`monitoring` | Expose runtime metrics (e.g. Prometheus)
`lifecycle_hook` | Run logic on job events (future)

## 📊 Monitoring Plugin Example

    # plugins/prometheus_exporter.py
    from nuvom.plugins.contracts import Plugin
    from nuvom.plugins.registry import register_metrics_provider

    class PrometheusPlugin(Plugin):
        name = "prometheus"
        provides = ["monitoring"]

        def start(self, settings):
            from my_exporter import run_exporter
            run_exporter(port=settings.get("prometheus_port", 9150))

        def stop(self):
            ...

## 🧠 Best Practices

- Keep plugins self-contained.
- Use `settings` from `.env` or custom sources.
- Fail fast if required dependencies are missing.
- Avoid blocking inside `start()` — spawn threads if needed.
- Don’t forget `stop()` for graceful cleanup.

## 🚦 CLI Support

Command | Description
--- | ---
`nuvom plugin test` | Validates and loads plugins
`nuvom plugin list` | Lists registered plugin types
`nuvom plugin inspect` | Shows metadata for one plugin

## 🚧 Roadmap (Future Plugin Hooks)

Feature | Status
--- | ---
`before_job`, `after_job` | [ ] Planned (via plugin)
`metrics_provider` interface | ✅ Prometheus supported
CLI plugin extensions | [ ] Future
Multi-process plugin runners | [ ] Future

## 🧩 Summary

Plugins allow you to:

- Add new backends (queue, result)
- Hook into Nuvom’s lifecycle
- Export runtime metrics
- Customize behavior without modifying Nuvom core

> Plugins make Nuvom truly pluggable. Add what you need — nothing more.

July 16, 2025