Get your task together!
By Sep Ehr
https://github.com/seperman
http://zepworks.com
Message Queue are the basic functionality of passing, holding, and delivering messages
Example: Redis, RabbitMQ
Tasks Queue manage work to be done and is considered a type of message queue
Example: Celery
in Python
| Solution | Stars on git | Downloads/mo |
|---|---|---|
| Celery | 4600 | 400,000 |
| RQ (Redis Queue) | 2600 | 40,000 |
| ⤿ Django RQ | 428 | 13,000 |
| Huey | 824 | 3,000 |
| MrQ (Mr. Q) | 340 | 5,000 |
| Taskmaster | 346 | 1,000 |
Popularity
| Solution | Stars on github |
|---|---|
| Celery | Instagram, Mozilla, Truecar |
| RQ (Redis Queue) | ? |
| ⤿ Django RQ | ? |
| Huey | ? |
| MrQ (Mr. Q) | Pricing Assistant (creator) |
| Taskmaster | Disqus (creator) |
Who uses them? Everyone.
Image from parallel programming in Python book
Client ⥂ Redis ⥄ Worker
from celery import Celery
app = Celery('tasks', broker='amqp://guest@localhost//')
@app.task
def add(x, y):
import time; sleep(5*60)
return x + y
------------------
>>> from tasks import add
>>> result = add.delay(4, 4)
>>> result.ready()
False
5 minutes later:
>>> result.ready()
Truefrom rq import Queue
from redis import Redis
from somewhere import count_words_at_url
# Tell RQ what Redis connection to use
redis_conn = Redis()
# no args implies the default queue
q = Queue(connection=redis_conn)
# Delay execution of count_words_at_url('http://nvie.com')
job = q.enqueue(count_words_at_url, 'http://nvie.com')
print job.result # => None
# Now, wait a while, until the worker is finished
time.sleep(2)
print job.result # => 889Monitoring
RQ Dashboard
MRQ dashboard
@shared_task
def test_progressbar(user_id=1):
from time import sleep
from django.utils.safestring import mark_safe
with celery_progressbar_stat(current_task, user_id) as c_stat:
for i in range(0, 101):
if c_stat.is_killed:
c_stat.report("Terminating task", e="test_err3", fatal=True)
sleep(.3)
if i == 6:
logger.info("test progress bar at 6%")
c_stat.report("Error: This error should show up", e="test_err",
sticky_msg=mark_safe("<p>TEST STICKY ERROR.</p>
<img src='https://someimage.jpeg'>"))
if i == 16:
logger.info("test progress bar at 16%")
c_stat.report("Error again: This error should show up too",
e="test_err2")
if i == 22:
logger.info("test progress bar at 22%")
c_stat.report("Error: This error should show NOT up since
it is raised before", e="test_err2")
c_stat.percent = i| Celery | RQ | |
|---|---|---|
| Complexity of code | Very complicated | Easy to understand |
| Documentation | Take a while to read | Simple |
| Monitoring | Flower | RQ Dashboard |
| message brokers | RabbitMQ, Redis, MongoDB | Redis |
| result backends | RabbitMQ, Redis, Memcached, MongoDB, Cassandra,... | Redis |
| Concurrency | Master-Slave processes | supervisord() + fork |
| Scheduler | Celerybeats | 3rd party |
| Language | Can send tasks from one language to another | Only Python |
| Subtasks | Can create tasks within tasks | Nope |
| Django support | Built-in | Django-rq |
Why RQ?
It all comes down to simplicity.
and...
Use Celery when:
RQ graph
Celery graph
And for your pleasure...
Django graph
Thank You
Get your task together!
By Sep Ehr
https://github.com/seperman
http://zepworks.com
https://www.linkedin.com/in/sepehr
More info
https://www.djangopackages.com/grids/g/workers-queues-tasks/
http://stackoverflow.com/questions/13440875/pros-and-cons-to-use-celery-vs-rq