Background Tasks in Python with RQ
Last updated October 11, 2024
Table of Contents
RQ (Redis Queue) makes it easy to add background tasks to your Python applications on Heroku. RQ uses a Redis database as a queue to process background jobs. To get started using RQ, you need to configure your application and then run a worker process in your application.
Configuration
To setup RQ and its dependencies, install it using pip:
$ pip install rq
Be sure to add rq
to your requirements.txt
file as well.
Create a worker
Now that we have everything we need to create a worker process, let’s create one.
Create a file called worker.py
. This module will listen to queued tasks and process them as they are received.
import os
import redis
from rq import Worker, Queue, Connection
listen = ['high', 'default', 'low']
redis_url = os.getenv('REDIS_URL', 'redis://localhost:6379')
conn = redis.from_url(redis_url)
if __name__ == '__main__':
with Connection(conn):
worker = Worker(map(Queue, listen))
worker.work()
Now you can run your new worker process:
$ python worker.py
Queuing jobs
To send a job to your new Redis Queue, you need to send your jobs to Redis in your code. Let’s pretend we have a blocking function in an external module, utils.py
:
import requests
def count_words_at_url(url):
resp = requests.get(url)
return len(resp.text.split())
In your application, create a RQ queue:
from rq import Queue
from worker import conn
q = Queue(connection=conn)
And enqueue the function call:
from utils import count_words_at_url
result = q.enqueue(count_words_at_url, 'http://heroku.com')
The blocking function will automatically be executed in the background worker process.
Deployment
To deploy your new worker system to Heroku, you need to add the worker process to the Procfile in the root of the project.
worker: python worker.py
Additionally, provision an instance of the Heroku Key-Value Store (heroku-redis) add-on and deploy with a git push
.
$ heroku addons:create heroku-redis
----> Adding heroku-redis to example-app... done, v10 (free)
$ git push heroku main
Counting objects: 5, done.
Delta compression using up to 4 threads.
...
Once everything’s pushed up, scale your workers according to your needs:
$ heroku scale worker=1
Scaling worker processes... done, now running 1
Troubleshooting
View worker process output by filtering the logs with the -p
flag and the name of the worker
process type.
$ heroku logs -t -p worker
The worker process can be manually invoked for further isolation.
$ heroku run worker
Running worker attached to terminal... up, run.1