Background tasks
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.