Skip to main content

Background tasks

Added in 1.0.19

All Chassis external tasks use WorkerTaskDTO, WorkerProvider, and WorkerService. A task defines its handler, queue, and execution rules once. Only the provider imports a worker library or converts those rules to its API. Import/export is the first built-in task; new tasks use the same contract.

Provider selection​

CHASSIS_WORKER_PROVIDER = 'auto' selects the first available provider from CHASSIS_WORKER_PROVIDERS. Defaults are Dramatiq, then Celery. Select a provider by its name, or use 'none' to disable workers. An explicit selection does not fall back when unavailable; unknown names raise ImproperlyConfigured. Installing a library alone is not sufficient: the project must configure it.

CHASSIS_WORKER_PROVIDER = 'dramatiq'

Chassis reuses the project broker. Configure it before registering tasks. Availability detects integration configuration, not broker or worker health.

Tasks and dispatch​

from django_chassis.dto import WorkerTaskDTO
from django_chassis.services import WorkerService

refresh_report = WorkerTaskDTO(
name='project.refresh_report',
handler='project.tasks.refresh_report',
queue='project-reports'
)

WorkerService.register_tasks(tasks=(refresh_report,))
WorkerService.enqueue(task=refresh_report, kwargs={'report_id': '123'})

The handler is a dotted import path to a function accepting keyword arguments. Payloads contain JSON values only; pass identifiers instead of model instances or UUID objects. Dispatch validates and copies the payload immediately, then publishes after transaction.on_commit(). Rollbacks publish nothing. This is not a transactional outbox; an application outbox is needed to bridge a failure between commit and publication.

WorkerTaskDTO.run(**kwargs) executes the handler. The compatibility calls task(**kwargs) and task.delay(**kwargs) execute or enqueue through the same contract; delay() returns None, independent of the transport.

Task defaults: three retries, 1–30 second backoff, five-minute time limit, one-day max age, queue chassis-default. Durations are in milliseconds; providers convert units where necessary. Override the metadata on the task, not in each provider's copy of the handler.

Registration in worker processes​

After Django and the broker are initialized, use one registration call:

import django

django.setup()

from django_chassis.services import WorkerService

WorkerService.register_tasks()

This registers the built-in django_chassis.worker_tasks.TASKS registry with the selected provider. Importing django_chassis.tasks also registers it for integrations that discover Django task modules. Repeated registration is safe with the built-in providers. If workers use named queues, include the queues from their task definitions. Configure Django connection cleanup middleware in the project integration.

Additional providers​

WorkerProvider is a structural protocol with one name, is_available(), register(task=...), and enqueue(task=..., kwargs=...). Both methods receive a WorkerTaskDTO; neither receives import/export-specific arguments. Transport adapters must register the handler, translate execution rules, publish JSON messages, and provide safe repeated registration. The Chassis service owns commit handling, so adapters publish immediately when enqueue() is called.

A third-party provider needs no changes to forms, tasks, dispatch, or Chassis:

CHASSIS_WORKER_PROVIDERS = (
'project.workers.CustomWorkerProvider',
'django_chassis.providers.dramatiq_worker_provider.DramatiqWorkerProvider',
'django_chassis.providers.celery_worker_provider.CeleryWorkerProvider'
)
CHASSIS_WORKER_PROVIDER = 'custom' # CustomWorkerProvider.name

Registry order sets priority in 'auto' mode. The deprecated CeleryAvailabilityService remains solely for old integrations; shared code uses WorkerService.is_available().

See also​

Local Python queue​

PythonQueueWorkerProvider uses the same task definitions and enqueue contract for a process-local daemon thread. It is not in the default auto-selection list; pass provider=PythonQueueWorkerProvider() to WorkerService.enqueue() or add its class path to a custom provider registry. Import/export keeps the existing PYTHON_QUEUE choice, now dispatching through this adapter after commit.

The local queue is best effort: it has no durable storage, retry scheduler, or hard execution timeout. External worker retry/age/time metadata is not enforced in this mode. It suits development or a single web process.