Skip to main content
The dispatcher system is responsible for executing background tasks in AWX. It manages worker processes, consumes messages from queues, and runs Python code to accomplish various tasks.

Overview

AWX uses the dispatcherd library for all task management. This is a dedicated task queue system that distributes work across machines in an AWX installation.

Key Components

Dispatcherd Library

AWX uses the dispatcherd library for task management:

Task Decorator

Tasks are decorated using:

Task Queues and Workers

Task Queue Abstraction

AWX uses a Task Queue abstraction to distribute work: Input: Unit of work called a Task Workers: Dedicated processes on every AWX node that monitor queues Communication: Via distributed queues using PostgreSQL’s pg_notify

Clustered Installations

Clustered AWX installations consist of:
  • Multiple workers spread across every node
  • High availability
  • Horizontal scaling

Message Types

Direct Messages

Bound directly to a specific named queue. Example: Launching a Job Template
  1. AWX looks at available capacity
  2. Chooses an Execution Node
  3. Publishes message to node-specific queue
  4. Dispatcher on that node listens for events
Characteristics:
  • Targeted to specific node
  • Consumed by one worker process
  • Used for job execution, inventory updates, etc.

Shared Direct Queues

Some direct queues are bound by every AWX node. Example: Inventory deletion task
  • Any available node may perform the work
  • First available worker processes the task

Fanout Messages

Sent out in a broadcast fashion. Example: Changing a setting in AWX API
  • Message broadcast to every AWX node
  • Code runs on every node
  • Used for cache invalidation, configuration updates
Characteristics:
  • Broadcast to all nodes
  • Every node processes the message
  • Ensures cluster-wide consistency

Defining Tasks

Function-Based Tasks

Simple functions decorated with @task():

Class-Based Tasks

Classes with a run() method:

Task Location

Tasks are defined in awx.main.tasks module:

Running Tasks

Publishing Tasks

To run a task in the background:

Message Format

When you run apply_async(), a JSON message is composed:

Task Execution

When a worker receives the message:
  1. Deserialize: Parse JSON message
  2. Import: Import the task callable
  3. Execute: Run the Python code
  4. Return: Task completes, result may be stored

Dispatcher Implementation

The Dispatcher Process

Every node runs awx-manage dispatcherd:
Responsibilities:
  • Uses kombu library for message consumption
  • Consumes from appropriate queues for the node:
    • Default shared queue
    • Node-specific queue (by hostname)
    • Broadcast queue
  • Manages pool of child processes
  • Distributes inbound messages to workers

Worker Pool

The dispatcher manages a pool of child processes:
Worker scaling:
  • Minimum workers: 4 (default)
  • Maximum workers: 60 (default)
  • Auto-scales based on load

Task Resolution

The dispatcher resolves tasks by dotted path:

Running Tasks

Workers execute tasks via run_callable():

Dispatcher Control

dispatcherctl Command

The awx-manage dispatcherctl command provides debugging capabilities:

Check Status

Information shown:
  • Worker PIDs
  • Tasks sent to each worker
  • Tasks completed
  • Queue size per worker
  • Memory usage (RSS)
  • Currently running tasks with UUIDs

List Running Tasks

Returns UUIDs of currently running tasks (corresponds to main_unifiedjob.celery_task_id in database).

Task Categories

Housekeeping Tasks

Background maintenance and scheduling:
  • run_task_manager: Periodic task that schedules jobs
  • run_dependency_manager: Creates job dependencies
  • run_workflow_manager: Manages workflow execution
See Task Manager documentation for details.

Heartbeats and Capacity

Periodic tasks running on every node:
Purpose:
  • Record node heartbeat
  • Calculate and report capacity
  • Reap jobs from dead nodes

Job Execution Tasks

Run Ansible playbooks and commands:

Administrative Tasks

Maintenance and cleanup:

Notification Tasks

Send notifications:

Callback Receiver

Special dispatcher process for handling Ansible callback events:
Purpose:
  • Receive Ansible events from running jobs
  • Process event data
  • Save to database for UI display

Task Routing

Queue Selection

Tasks can be routed to specific queues:

Execution Node Selection

For job execution:
  1. Task Manager selects execution node
  2. Considers capacity and instance groups
  3. Routes task to node-specific queue
  4. Dispatcher on that node processes task

Monitoring and Debugging

Check Dispatcher Health

Task Tracking

Tasks have UUIDs that can be tracked:

Common Issues

Dispatcher not running:
Workers stuck:
High memory usage:

Performance Tuning

Worker Pool Size

Considerations:
  • More workers = more concurrency
  • Each worker consumes memory
  • Balance based on workload and resources

Queue Backlog

Monitor queue depth:
Large queue sizes indicate workers are overloaded.

Task Prioritization

Currently AWX uses FIFO (First In, First Out) for task processing. Future enhancements may include:
  • Priority queues
  • Task preemption
  • Resource-based scheduling

Security Considerations

Task Validation

Only tasks starting with awx. are allowed:
This prevents arbitrary code execution.

Credential Handling

Credentials are never passed in task arguments:
  • Retrieved from database within task
  • Decrypted at runtime
  • Never logged

Process Isolation

Worker processes are isolated:
  • Separate process per task
  • Failures don’t affect other tasks
  • Resource limits via cgroups (in containers)

Next Steps