RabbitMQ Consumer Services
April 27, 2026 · View on GitHub
RabbitMQ consumers are background worker processes that handle asynchronous job processing for compute-intensive tasks.
Overview
- Technology: RabbitMQ message broker, Python consumers
- Location:
listeners/directory - Deployment: Systemd services
- Purpose: Async processing of ProjectR, analysis, and other long-running tasks
Architecture
Flask API
↓
RabbitMQ Queue
↓
Consumer Workers (systemd)
↓
Job Processing (ProjectR, Analysis, etc.)
↓
Result Storage (Database, File System)
Available Consumers
Gosling Upload Consume
Facilitates uploading of track files for the epigenome uploader.
- Listener:
listeners/gosling_upload_consumer.py - Queue:
trackhub_copy_jobs - Service Template:
systemd/gosling-upload-consumer@.service - Service Group:
systemd/gosling-upload-consumer.target
ProjectR Consumer
Processes matrix projection jobs for dimensionality reduction.
- Listener:
listeners/projectr_consumer.py - Queue:
projectr_jobs - Service Template:
systemd/projectr-consumer@.service - Service Group:
systemd/projectr-consumer.target
Additional Consumers
More consumers can be added following the same pattern:
- Analysis pipeline consumer
- Dataset processing consumer
- Export generation consumer
Setup
Prerequisites
-
RabbitMQ Server
sudo apt install rabbitmq-server sudo systemctl enable rabbitmq-server sudo systemctl start rabbitmq-serverSee also:
docs/developer/setup/rabbitmq.md -
Python Dependencies
pip install pika # RabbitMQ Python client -
R and Packages (for ProjectR)
See:
docs/developer/setup/r_rpy2.md
Configuration
Configure in gear.ini:
[<service]
;; 0 - disable RabbitMQ, 1 - enable. Disabling could lead to potential server crashes if many jobs are run simultaneously
queue_enabled = 0
queue_host = localhost
Installing Services
# Copy service files to systemd directory
cd systemd
sudo cp projectr-consumer@.service /etc/systemd/system/
sudo cp projectr-consumer.target /etc/systemd/system/
sudo cp gosling-upload-consumer@.service /etc/systemd/system
sudo cp gosling-upload-consumer.target /etc/systemd/system
# Reload systemd
sudo systemctl daemon-reload
# Enable services to start on boot
sudo systemctl enable projectr-consumer.target gosling-upload-consumer.target
Starting Services
Using Service Target (Recommended)
Start all consumers in the group:
# Start all ProjectR consumers
sudo systemctl start projectr-consumer.target gosling-upload-consumer.target
# Check status
sudo systemctl status projectr-consumer.target gosling-upload-consumer.target
Individual Workers
Start specific numbered workers:
Using projectr-consumer as an example.
# Start worker 1
sudo systemctl start projectr-consumer@1.service
# Start worker 2
sudo systemctl start projectr-consumer@2.service
# Check status
sudo systemctl status projectr-consumer@1.service
Scaling Workers
Start multiple workers for parallel processing:
# Start 4 workers
sudo systemctl start projectr-consumer@1.service
sudo systemctl start projectr-consumer@2.service
sudo systemctl start projectr-consumer@3.service
sudo systemctl start projectr-consumer@4.service
# Or use target to manage predefined workers
sudo systemctl start projectr-consumer.target
Monitoring
These use projectr-consumer as an example
Service Status
# Check all consumers
systemctl status 'projectr-consumer@*'
# Check specific consumer
sudo systemctl status projectr-consumer@1.service
Logs
# Follow logs for consumer 1
sudo journalctl -u projectr-consumer@1.service -f
# View recent logs
sudo journalctl -u projectr-consumer@1.service -n 100
# View logs for all consumers
sudo journalctl -u 'projectr-consumer@*' -f
RabbitMQ Monitoring
# Command line
sudo rabbitmqctl list_queues
sudo rabbitmqctl list_consumers
# Web UI (if management plugin enabled)
http://localhost:15672
# Default credentials: guest/guest
Enable management plugin:
sudo rabbitmq-plugins enable rabbitmq_management
Systemd Service Template
The @ symbol in service filenames indicates a template. This allows spawning multiple instances.
Example: projectr-consumer@.service
[Unit]
Description=ProjectR Consumer Worker %i
After=network.target rabbitmq-server.service
[Service]
Type=simple
User=www-data
WorkingDirectory=/var/www/gEAR
ExecStart=/usr/bin/python3 listeners/projectr_consumer.py
Restart=always
RestartSec=10
[Install]
WantedBy=projectr-consumer.target
Usage:
%iis replaced with instance numberprojectr-consumer@1.service→ Worker 1projectr-consumer@2.service→ Worker 2
Target Files
Target files group related services together.
Example: projectr-consumer.target
[Unit]
Description=ProjectR Consumer Workers
Wants=projectr-consumer@1.service projectr-consumer@2.service
[Install]
WantedBy=multi-user.target
Benefits:
- Start/stop all workers with one command
- Manage workers as a group
- Ensure dependencies are met
Writing Custom Consumers
Basic Consumer Template
#!/usr/bin/env python3
import pika
import json
import sys
def callback(ch, method, properties, body):
"""Process incoming job"""
job_data = json.loads(body)
# Process job
result = process_job(job_data)
# Acknowledge message
ch.basic_ack(delivery_tag=method.delivery_tag)
return result
def process_job(data):
"""Your job processing logic"""
# Implement your processing here
pass
def main():
# Connect to RabbitMQ
credentials = pika.PlainCredentials('guest', 'guest')
parameters = pika.ConnectionParameters(
host='localhost',
credentials=credentials
)
connection = pika.BlockingConnection(parameters)
channel = connection.channel()
# Declare queue
channel.queue_declare(queue='my_jobs', durable=True)
# Set QoS (prefetch count)
channel.basic_qos(prefetch_count=1)
# Start consuming
channel.basic_consume(
queue='my_jobs',
on_message_callback=callback
)
print('Waiting for messages...')
channel.start_consuming()
if __name__ == '__main__':
try:
main()
except KeyboardInterrupt:
print('Interrupted')
sys.exit(0)
Creating Service File
- Create consumer script in
listeners/ - Create systemd service file in
systemd/ - Copy to
/etc/systemd/system/ - Start service
Troubleshooting
Consumer Not Processing Jobs
Check RabbitMQ connection:
# Verify RabbitMQ is running
sudo systemctl status rabbitmq-server
# Check queue has messages
sudo rabbitmqctl list_queues
Check consumer logs:
sudo journalctl -u projectr-consumer@1.service -n 50
Verify gear.ini configuration:
- Check RabbitMQ credentials
- Verify
use_rabbitmq = true
Consumer Crashes
Check for errors in logs:
sudo journalctl -u projectr-consumer@1.service -p err
Common issues:
- Python import errors (missing dependencies)
- R package errors (ProjectR consumer)
- Database connection issues
- File permission errors
Restart consumer:
sudo systemctl restart projectr-consumer@1.service
Jobs Stuck in Queue
Verify consumers are running:
systemctl status 'projectr-consumer@*'
Check message acknowledgment:
- Ensure
basic_ack()is called after processing - Check for exceptions in processing code
Purge queue (if needed):
sudo rabbitmqctl purge_queue projectr
Warning: This deletes all messages!
Performance Tuning
Worker Count
Number of workers depends on:
- Available CPU cores
- Memory per job
- Job duration
Example:
- ProjectR jobs: 1-4 workers (memory intensive)
- Light jobs: Up to core count
Prefetch Count
Controls how many messages a worker fetches at once:
channel.basic_qos(prefetch_count=1) # Process one at a time
channel.basic_qos(prefetch_count=5) # Prefetch 5 messages
Lower prefetch = Better load balancing Higher prefetch = Better throughput (if jobs are quick)
Queue Durability
Make queues survive RabbitMQ restarts:
channel.queue_declare(queue='my_jobs', durable=True)
Send persistent messages:
channel.basic_publish(
exchange='',
routing_key='my_jobs',
body=message,
properties=pika.BasicProperties(delivery_mode=2) # Persistent
)
Best Practices
- Always acknowledge messages after successful processing
- Handle exceptions gracefully to avoid losing jobs
- Use durable queues for important jobs
- Monitor queue length to detect processing issues
- Set appropriate timeouts for long-running jobs
- Log errors for debugging
- Test locally before deploying to production
Maintenance
Updating Consumer Code
# Pull latest code
git pull origin devel
# Restart consumers
sudo systemctl restart projectr-consumer.target
Viewing Queue Statistics
# Via CLI
sudo rabbitmqctl list_queues name messages consumers
# Via management UI
http://localhost:15672/#/queues
Clearing Old Messages
If messages are stuck or invalid:
# Purge specific queue
sudo rabbitmqctl purge_queue projectr
Related Documentation
docs/developer/setup/rabbitmq.md- RabbitMQ setupdocs/developer/setup/r_rpy2.md- R setup for ProjectRsystemd/README.md- Systemd service management- RabbitMQ docs: https://www.rabbitmq.com/documentation.html
Getting Help
- Check RabbitMQ logs:
/var/log/rabbitmq/ - Review consumer logs via journalctl
- Test connection with simple producer/consumer scripts
- Create GitHub issue with "rabbitmq" label