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.
Before adding the worker
compose::add is served by a running Compose daemon. Keep the engine and a daemon for this project
running in separate terminals before using any of the commands below. If this project does not have
a Compose file yet, create worker-compose.yaml containing containers: {} first.
iii compose is an intentional verbless daemon invocation, documented in the
CLI reference. The -n used below is the short form of
--namespace for iii call.
Run the remaining commands from a third terminal in that same project directory:
This page covers common queue patterns. For the complete configuration and function API, 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, call the function with the enqueue action. Thequeue field of the action names
the queue to use, so configure that queue in the queue worker configuration first.
Enqueue a function
An enqueue call is a function call with the enqueue action. The queue runs the function later, and the caller gets a receipt before the function starts:- Node / TypeScript
- Python
- Rust
- Go
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).Consume messages
An observer ofqueue::on-message with a topic in its args runs the target function for each
message published to that topic, with the message data as the input. A normal return acknowledges
the message. An error retries it, and the last failed delivery moves the message to the dead-letter
queue.
In a worker, register the consumer function and observe queue::on-message with the topic. If you
do not have a worker yet, follow Create a new worker, then edit its
source:
- Node / TypeScript
- Python
- Rust
- Go
filters select messages by their data as input. A message that the filters reject is
acknowledged without running the target.
Publish a message
With the consumer running, publish to its topic:Subscriber args
Every observer ofqueue::on-message carries its subscription in args. The args fall into three
classes.
Consumption
topic names the topic to consume. It is required.
- Node / TypeScript
- Python
- Rust
- Go
Retries
max_retries counts the deliveries of one message, the first one included, before the message moves
to the dead-letter queue. The default is 3. backoff_ms sets the first retry delay, and each later
retry doubles it, so a message that always fails reaches the dead-letter queue about 3 seconds after
it is published.
- Node / TypeScript
- Python
- Rust
- Go
observers.activation_timeout_ms (30 seconds by
default). A target that runs longer fails the delivery with TIMEOUT, which is retried like any
other failure. For longer jobs, raise it in the
engine config.
Delivery
queue_config sets the delivery settings of this subscriber, for example { type: "fifo" } to
process messages one at a time. group names the consumer group: subscribers that name the same
group share one consumer, which handles each message once.
- Node / TypeScript
- Python
- Rust
- Go
A subscriber without a
group has its own durable queue, so two observers of one topic each
receive every published message. To spread one stream of messages across several consumers, give
their observers the same group.Inspecting Queue Topics
engine::queue::list_topics lists every topic. engine::queue::topic_stats reports the counters of
one topic: depth is the messages waiting for the consumer and dlq_depth is the dead-lettered
messages. A topic with no waiting messages reports depth: 0. For a named queue, consumer_count
reports its active delivery slots. A topic that no observer subscribes to does not register, so
there is nothing to inspect.
List every topic:
emails topic:
The list holds two kinds of queue. A pub/sub topic appears once an observer subscribes to it and
shows
broker_type: "builtin". A configured named queue shows broker_type: "function_queue".Inspecting Dead Letter Queue Messages
A message reaches the dead-letter queue only once its target 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 all of its deliveries and dead-letters.
- Node / TypeScript
- Python
- Rust
- Go
Listing topics with dead-lettered messages
Browsing dead-lettered messages
Redriving dead-lettered messages
Restore the handler, 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: