Core Concepts¶
Nuvom is built around a small number of powerful, composable concepts. Mastering these is key to using (and extending) the system effectively, now including built-in scheduling.
Task¶
A Task is a Python function decorated with @task(...). It becomes a job template.
@task(retries=2, timeout_secs=5)
def send_email(to, body):
...
Each task carries metadata like retry policy, timeout, whether to store results, and scheduling configuration.
Job¶
A Job is a serialized instance of a task + arguments.
job = send_email.delay("alice@example.com", "hello")
Jobs are queued and executed by workers. You can inspect metadata, results, status, and tracebacks.
Worker¶
A Worker pulls jobs from the queue and executes them.
Nuvom workers:
- Run in parallel (multi-threaded)
- Respect timeouts, retries, and lifecycle hooks
- Use safe shutdown behavior (
SIGINTtriggers graceful stop) - Work with plugin-registered backends
- Execute scheduled jobs seamlessly, respecting intervals, cron expressions, and one-off timings
Start a worker pool with:
nuvom runworker
Dispatcher¶
The Dispatcher converts function calls into jobs.
.delay()→ single job.map()→ batch jobs.schedule()→ schedule jobs (one-off, interval, or cron)- Supports metadata injection
- Automatically selects queue backend from config
Queue Backend¶
A Queue Backend stores jobs awaiting execution.
Built-in:
MemoryJobQueue– fast, ephemeralFileJobQueue– atomic, file-based persistenceSQLiteJobQueue– relational queue with retries + visibility timeouts
Custom backends can be added via plugins. Each queue implements:
enqueue(job)dequeue(timeout)pop_batch(n)qsize()clear()
Result Backend¶
Stores results or errors from executed jobs.
Built-in:
MemoryResultBackendFileResultBackendSQLiteResultBackend
Backends implement:
set_result(id, func, result)set_error(id, func, exc)get_result(id)get_error(id)get_full(id)list_jobs()
Registry¶
The Task Registry maps task names → callables.
- Populated from
.nuvom/manifest.json - Supports dynamic registration (
force,silent) - Used by workers to resolve jobs → functions
Task Discovery¶
Uses AST parsing to find @task decorators.
- No runtime imports
- Supports
.nuvomignore - Results cached in
.nuvom/manifest.json - Updated via
nuvom discover tasks
Enables fast startup and avoids circular imports.
Scheduling¶
Scheduling is built into Nuvom tasks:
- One-off: run once at a specific time
- Interval: run repeatedly at fixed intervals
- Cron: run with cron expressions
Example:
from datetime import timedelta, datetime, timezone
# Run once at a specific time
send_email.schedule("alice@example.com", "hello", at=datetime(2025,8,25,12,0,tzinfo=timezone.utc))
# Run once after 30 seconds
send_email.schedule("alice@example.com", "hello", in_=timedelta(seconds=30))
# Run every 5 minutes
send_email.schedule("alice@example.com", "hello", interval=300)
# Cron-style: daily at midnight UTC
send_email.schedule("alice@example.com", "hello", cron="0 0 * * *")
Scheduled jobs integrate seamlessly with workers, retries, and plugins.
Plugins¶
Extend Nuvom dynamically:
- Queue backends
- Result backends
- Monitoring hooks
- Lifecycle-aware systems
Defined in .nuvom_plugins.toml and validated with nuvom plugin test.
Summary Table¶
| Concept | Role |
|---|---|
@task |
Defines metadata for background execution, including scheduling |
Job |
A task + args, queued for execution |
Worker |
Executes jobs from the queue, including scheduled jobs |
Queue |
Stores jobs awaiting execution |
Backend |
Stores results, errors, and metadata |
Dispatcher |
Converts function calls into jobs, supports .delay(), .map(), .schedule() |
Registry |
Maps task names to functions |
Discovery |
Scans source code and builds task manifest |
Plugin |
Dynamically extends Nuvom’s capabilities |
Scheduler |
Manages one-off, interval, and cron jobs across workers |