Queue processors

Zulip uses RabbitMQ to manage a system of internal queues. These are used for a variety of purposes:

Needless to say, the RabbitMQ-based queuing system is an important part of the overall Zulip architecture, since it's in critical code paths for everything from signing up for account, to rendering messages, to delivering updates to clients.

We use the pika library to interface with RabbitMQ, using a simple custom integration defined in zerver/lib/queue.py.

Adding a new queue processor

To add a new queue processor:

The queue will automatically be added to the list of queues tracked by scripts/nagios/check-rabbitmq-consumers, so Nagios can properly check whether a queue processor is running for your queue. You still need to update the sample Nagios configuration in puppet/zulip_ops manually.

Publishing events into a queue

You can publish events to a RabbitMQ queue using the queue_json_publish function defined in zerver/lib/queue.py.

An interesting challenge with queue processors is what should happen when queued events in Zulip's backend tests. Our current solution is that in the tests, queue_json_publish will (by default) simple call the consume method for the relevant queue processor. However, queue_json_publish also supports being passed a function that should be called in the tests instead of the queue processor's consume method. Where possible, we prefer the model of calling consume in tests since that's more predictable and automatically covers the queue processor's code path, but it isn't always possible.

Clearing a RabbitMQ queue

If you need to clear a queue (delete all the events in it), run ./manage.py purge_queue <queue_name>, for example:

./manage.py purge_queue user_activity

You can also use the amqp tools directly. Install amqp-tools from apt and then run:

amqp-delete-queue --username=zulip --password='...' --server=localhost \
   --queue=user_presence

with the RabbitMQ password from /etc/zulip/zulip-secrets.conf.