MiqQueue & Job Dispatcher
Relevant source files
The following files were used as context for generating this wiki page:
The MiqQueue system is the primary asynchronous messaging framework within ManageIQ, designed to distribute work across distributed servers and workers. It allows the system to offload long-running or resource-intensive operations—such as provisioning, report generation, and capacity planning—to specialized workers, ensuring the user interface remains responsive.
The system relies on a database-backed queue where messages specify a target class, method, and arguments. Workers "check out" these messages based on their assigned roles and zones, execute the requested logic, and provide feedback via callbacks and the MiqTask system.
Sources: app/models/miq_queue.rb:1-25, app/models/miq_worker.rb:1-15
MiqQueue Architecture
The queue acts as a broker between the requestor and the executor. Every message in the queue is an instance of the MiqQueue model.
Message Attributes and Routing
Messages are routed using three primary criteria:
- Zone: Limits execution to servers within a specific geographical or logical segment. If set to
nil, any zone can process the message. - Role: Ensures only workers with the necessary functional role (e.g.,
ems_operations,reporting,smartstate) pick up the task. - Queue Name: Identifies the specific worker pool intended to process the work (defaults to
generic).
Sources: app/models/miq_queue.rb:4-18, app/models/miq_queue.rb:147-175
Priority Levels
MiqQueue uses a numeric priority system where lower values indicate higher urgency.
| Constant | Value | Description |
|---|---|---|
MAX_PRIORITY | 0 | Highest possible urgency. |
HIGH_PRIORITY | 20 | Used for user-initiated actions waiting for a result. |
MEDIUM_PRIORITY | 50 | Standard background tasks (e.g., scheduled refreshes). |
NORMAL_PRIORITY | 100 | Default priority for most queue items. |
LOW_PRIORITY | 150 | Non-urgent background maintenance. |
MIN_PRIORITY | 200 | Lowest possible urgency. |
Sources: app/models/miq_queue.rb:27-34
Message Lifecycle states
Messages transition through several states during their lifecycle:
The diagram above illustrates the standard state transitions for a queue message from creation to completion or failure.
Sources: app/models/miq_queue.rb:83-93, app/models/miq_queue.rb:429-450
Message Delivery Logic
The deliver method is responsible for the actual execution of the queued task. It constantizes the class_name, finds the instance if an instance_id is provided, and invokes the method_name with the supplied args.
The Dispatching Process
- Context Setting: The system sets the
User.current_usercontext usinguser_id,group_id, andtenant_idstored in the message. - Execution: The method is invoked within a
Timeout.timeoutblock defined bymsg_timeout. - Error Handling: If a
MiqQueueRetryLaterexception is raised, the message is requeued with a newdeliver_ontimestamp. - Callbacks: After execution, if a
miq_callbackis defined, the system invokes the callback method on the specified class/instance to notify the parent process of the result.
Sources: app/models/miq_queue.rb:393-426, app/models/miq_queue.rb:456-470
MiqTask Integration
MiqTask provides a persistent record of the progress of a queued operation. While MiqQueue is ephemeral (records are usually destroyed upon completion), MiqTask remains for historical tracking and UI status updates.
Generic Action with Callback
The MiqTask.generic_action_with_callback method is a common pattern for linking tasks and queue items.
This sequence shows how ManageIQ ensures that asynchronous work is tracked from initiation to final result.
Sources: app/models/miq_task.rb:230-255
Task States and Status
Tasks track both a state (process lifecycle) and a status (result quality).
| Field | Possible Values |
|---|---|
| State | Initialized, Queued, Active, Finished |
| Status | Ok, Warn, Error, Timeout, Unknown |
Sources: app/models/miq_task.rb:6-26
Worker and Server Interaction
Worker Polling
Workers use the MiqQueue.get method to retrieve work. This method includes complex SQL to ensure:
- Only messages for the worker's zone and roles are retrieved.
- High-priority messages are processed first.
- Messages associated with a specific
server_guidare only picked up by that server. - Avoids picking up multiple messages for the same
task_idif one is already being processed (state = 'dequeue').
Sources: app/models/miq_queue.rb:233-255
Status Management
The MiqServer::StatusManagement module integrates with the queue to log performance metrics. It monitors the count of queue items by state, zone, and role to identify bottlenecks in the dispatcher.
Sources: app/models/miq_server/status_management.rb:79-82
Common Implementation Examples
Provisioning Tasks
MiqRequestTask utilizes the queue to handle state machine transitions. The execute_queue method puts the task into the queue to call the execute method, effectively moving the provisioning state machine to the next phase asynchronously.
Sources: app/models/miq_request_task.rb:149-174
Widget Content Generation
MiqWidget generates dashboard content by queueing generate_content. It creates an MiqTask to track the overall progress across multiple user groups and utilizes a callback (generate_content_complete_callback) to update the task percentage as each group's content is finalized.
Sources: app/models/miq_widget.rb:99-122, app/models/miq_widget.rb:181-209
Summary
The MiqQueue and Job Dispatcher system provide the backbone for scalability in ManageIQ. By decoupling request submission from execution, it allows the platform to handle massive workloads across many workers while providing consistent tracking via MiqTasks and resilient error handling through automated retries and timeouts.