iii-queue worker decouples producers from consumers: a function publishes a message to a named
topic and returns right away, and any function subscribed to that topic processes the message in the
background, with retries and a dead-letter queue (DLQ) for messages that keep failing.
This page is a quick tour. For the full functionality of the queue worker see the queue worker
docs.
Named Queues
When you need to control function execution for time consuming operations, or guarantee a certain number of retries then you can useTriggerAction.Enqueue to place that operation into a queue.
Creating a Queue
Queues are defined in theiii-queue worker’s config under queue_configs:
queue_configs entry accepts:
Enqueue functions
Enqueued functions are registered the same as any other call toworker.trigger with the one
difference being providing an action called TriggerAction.Enqueue to the trigger:
- Node / TypeScript
- Python
- Rust
Pub/Sub Queues
Queues can also be used in a publish/subscribe form when multiple listeners need to subscribe to the same data and it’s important that the messages be durable (ie. will succeed).Consuming messages
A consumer can bind to a message by registering a Trigger fordurable:subscriber trigger to it.
The engine runs the function once per message, passing the published data as the payload.
Returning normally acknowledges the message; throwing nacks it, so it is retried and eventually
dead-lettered.
- In a worker, register the consumer function and subscribe it to the topic. If you do not have a
worker yet, scaffold one with
iii worker init, then edit its source:
- Node / TypeScript
- Python
- Rust
- Add the worker to start it:
Publishing a message
With the consumer running, publish to its topic. The engine delivers thedata to every subscriber,
so email::send runs once per message:
Retries and delivery
Thedurable:subscriber trigger’s config controls how each subscriber consumes:
A failed delivery retries with exponential backoff (1 second, then 2 seconds) for up to 3 attempts,
then the message dead-letters.
queue_config accepts the following fields:
For example, to process messages strictly one at a time instead of concurrently, register the
trigger with a
fifo queue:
- Node / TypeScript
- Python
- Rust
Inspecting Queue Topics
These commands list both kinds of queue. A pub/sub topic appears once a function subscribes to it, and showsbroker_type: "builtin". (Publishing to a topic that nothing subscribes to does not
register it, so there is nothing to inspect.) A named queue appears as soon as its queue_configs
entry is defined, and shows broker_type: "function_queue".
List every topic (this inspects the emails topic from above):
depth is messages waiting for the consumer, dlq_depth is
dead-lettered). A topic whose consumer keeps up sits at depth: 0. For a named queue,
consumer_count reports its configured concurrency slots (10 for email-jobs):
Inspecting Dead Letter Queue Messages
A message reaches the dead-letter queue only once its subscribed function exhausts its retries, so the DLQ functions return empty until something fails.Forcing a message into the dead-letter queue
To see the DLQ populated, makeemail::send fail by changing the handler to throw. Each message
then fails its 3 delivery attempts (a few seconds with the exponential backoff) and dead-letters.
- Node / TypeScript
- Python
- Rust
Listing topics with dead-lettered messages
Browsing dead-lettered messages
Redriving dead-lettered messages
Fix the code back to what it was originally, then move the topic’s dead-lettered messages back to the main queue for reprocessing:Redriving or discarding a single message
To handle one message instead of the whole topic, pass theid from engine::queue::dlq_messages.
Redrive one message back to the main queue: