Important
You are browsing upcoming documentation for version 7.1 of OroCommerce, scheduled for release in 2027. Read the documentation for the latest LTS version to get up-to-date information.
See our Release Process documentation for more information on the currently supported and upcoming releases.
Consumption Modes
Consumption modes determine the order in which multiple queues are visited by the message consumer during a consumption cycle. When a consumer is bound to more than one queue, the consumption mode controls which queue is polled next. Different modes offer different trade-offs between fairness, priority handling, throughput, and starvation avoidance.
The consumption mode is selected via the --mode CLI option or the ORO_MQ_CONSUMPTION_MODE environment variable. The default mode is default.
Built-in Consumption Modes
default
Class: Oro\Component\MessageQueue\Consumption\QueueIterator\DefaultQueueIterator
Iterates over bound queues in a fixed round-robin order. Each queue gets exactly one poll before advancing to the next. After the last queue, the cycle restarts.
Consumption schema:
1 queue: Q1(1)
2 queues: Q1(1), Q2(1)
3 queues: Q1(1), Q2(1), Q3(1)
Each (1) means exactly one poll of that queue before moving on.
php bin/console oro:message-queue:transport:consume --queue=oro.default --queue=oro.system --mode=default
sequential-exhaustive
Class: Oro\Component\MessageQueue\Consumption\QueueIterator\SequentialExhaustiveQueueIterator
The first queue is fully drained (polled until idle) before the iterator advances to the next. After the last queue is exhausted, the cycle ends. This mode implements NotifiableQueueIteratorInterface and relies on the feedback loop (message-received / idle notifications) to detect when a queue is exhausted.
Consumption schema:
1 queue: Q1(*)
2 queues: Q1(*), Q2(*)
3 queues: Q1(*), Q2(*), Q3(*)
The asterisk (*) means the iterator stays on the current queue until it becomes idle.
php bin/console oro:message-queue:transport:consume --queue=oro.default --queue=oro.system --mode=sequential-exhaustive
strict-priority-interleaving
Class: Oro\Component\MessageQueue\Consumption\QueueIterator\StrictPriorityInterleavingQueueIterator
The first queue (Q1) is treated as the highest-priority queue. It is drained until idle, then exactly one message is consumed from the next lower-priority queue, then back to Q1, and so on. This ensures that the high-priority queue is always serviced first while lower-priority queues are not completely starved. Implements NotifiableQueueIteratorInterface.
Consumption schema:
1 queue: Q1(*)
2 queues: Q1(*), Q2(1)
3 queues: Q1(*), Q2(1), Q1(*), Q3(1)
4 queues: Q1(*), Q2(1), Q1(*), Q3(1), Q1(*), Q4(1)
php bin/console oro:message-queue:transport:consume --queue=oro.high --queue=oro.default --queue=oro.low --mode=strict-priority-interleaving
hierarchical-strict-priority-interleaving
Class: Oro\Component\MessageQueue\Consumption\QueueIterator\HierarchicalStrictPriorityInterleavingQueueIterator
A fully recursive version of strict-priority-interleaving. The sub-pattern of higher-priority queues is repeated until idle before a single poll of the next lower-priority queue. Implements NotifiableQueueIteratorInterface.
Consumption schema:
1 queue: Q1(*)
2 queues: Q1(*), Q2(1)
3 queues: ( Q1(*), Q2(1) )(*), Q3(1)
4 queues: ( ( Q1(*), Q2(1) )(*), Q3(1) )(*), Q4(1)
php bin/console oro:message-queue:transport:consume --queue=oro.critical --queue=oro.high --queue=oro.default --queue=oro.low --mode=hierarchical-strict-priority-interleaving
weighted-round-robin
Class: Oro\Component\MessageQueue\Consumption\QueueIterator\WeightedRoundRobinQueueIterator
Each queue is consumed for up to weight messages before advancing to the next. When a queue becomes idle before its weight is exhausted, the iterator advances immediately. Queues without an explicit weight setting default to 1. Implements NotifiableQueueIteratorInterface.
Consumption schema (where w1, w2, w3 are configured weights):
1 queue: Q1(w1)
2 queues: Q1(w1), Q2(w2)
3 queues: Q1(w1), Q2(w2), Q3(w3)
The weight is set via the weight queue setting in the --queue long notation:
php bin/console oro:message-queue:transport:consume --queue="name=oro.default,weight=5" --queue="name=oro.system,weight=2" --mode=weighted-round-robin
Creating Custom Consumption Modes
You can create a custom consumption mode by implementing a queue iterator and a corresponding factory, then registering them as tagged services.
Step 1: Create the Queue Iterator
Create a class implementing Oro\Component\MessageQueue\Consumption\QueueIterator\QueueIteratorInterface (which extends \Iterator<string, array>). The iterator key() returns the queue name and current() returns the queue settings array. Define a NAME constant for the mode name.
If the iterator needs feedback about whether messages were received or the queue was idle, implement Oro\Component\MessageQueue\Consumption\QueueIterator\NotifiableQueueIteratorInterface instead.
namespace Acme\Bundle\DemoBundle\Consumption\QueueIterator;
use Oro\Component\MessageQueue\Consumption\QueueIterator\QueueIteratorInterface;
class MyCustomQueueIterator implements QueueIteratorInterface
{
public const string NAME = 'my-custom-mode';
private array $keys;
private array $values;
private int $position = 0;
public function __construct(array $boundQueues)
{
$this->keys = array_keys($boundQueues);
$this->values = array_values($boundQueues);
}
public function current(): array
{
return $this->values[$this->position];
}
public function key(): string
{
return $this->keys[$this->position];
}
public function next(): void
{
++$this->position;
}
public function rewind(): void
{
$this->position = 0;
}
public function valid(): bool
{
return isset($this->keys[$this->position]);
}
}
Step 2: Create the Factory
Create a class implementing Oro\Component\MessageQueue\Consumption\QueueIterator\QueueIteratorFactoryInterface. The factory createQueueIterator(array $boundQueues, string $consumptionMode) method creates the iterator.
For notifiable iterators, inject a NotifiableQueueIteratorRegistryInterface and register the iterator via addQueueIterator().
namespace Acme\Bundle\DemoBundle\Consumption\QueueIterator;
use Oro\Component\MessageQueue\Consumption\QueueIterator\NotifiableQueueIteratorRegistryInterface;
use Oro\Component\MessageQueue\Consumption\QueueIterator\QueueIteratorFactoryInterface;
class MyCustomQueueIteratorFactory implements QueueIteratorFactoryInterface
{
private ?NotifiableQueueIteratorRegistryInterface $registry;
public function __construct(?NotifiableQueueIteratorRegistryInterface $registry = null)
{
$this->registry = $registry;
}
public function createQueueIterator(array $boundQueues, string $consumptionMode): \Iterator
{
$iterator = new MyCustomQueueIterator($boundQueues);
$this->registry?->addQueueIterator($iterator);
return $iterator;
}
}
Step 3: Register the Services
Tag the factory with oro_message_queue.consumption.queue_iterator_factory and set the consumption_mode attribute to your mode name.
services:
acme_demo.consumption.queue_iterator.my_custom_factory:
class: Acme\Bundle\DemoBundle\Consumption\QueueIterator\MyCustomQueueIteratorFactory
tags:
- { name: oro_message_queue.consumption.queue_iterator_factory, consumption_mode: my-custom-mode }
For notifiable iterators, also register a NotifiableQueueIteratorRegistry and a NotifiableConsumptionExtension:
services:
acme_demo.consumption.queue_iterator.my_custom_registry:
class: Oro\Component\MessageQueue\Consumption\QueueIterator\NotifiableQueueIteratorRegistry
acme_demo.consumption.queue_iterator.my_custom_factory:
class: Acme\Bundle\DemoBundle\Consumption\QueueIterator\MyCustomQueueIteratorFactory
arguments:
- '@acme_demo.consumption.queue_iterator.my_custom_registry'
tags:
- { name: oro_message_queue.consumption.queue_iterator_factory, consumption_mode: my-custom-mode }
acme_demo.consumption.queue_iterator.my_custom_extension:
class: Oro\Component\MessageQueue\Consumption\QueueIterator\NotifiableConsumptionExtension
arguments:
- '@acme_demo.consumption.queue_iterator.my_custom_registry'
tags:
- { name: oro_message_queue.consumption.extension, persistent: true }
Step 4: Use the Custom Mode
Once registered, the custom mode is available via the --mode option:
php bin/console oro:message-queue:transport:consume --queue=oro.default --mode=my-custom-mode