Recently I started to move Cubby Scott away from a cron and towards a queue. It's hard to be real time when you wake up a cron job once every 3 minutes. Lame. I'm also in the process of adding screenshots and content retrieval. Both take a good amount of time to process. The queue part was easy after reading Rabbits and Warrens and Working with Python and RabbitMQ. The problem came when I started working on the consumer, no one ever talks about the consumer. Well I'm going to give the consumer some love.
The consumer should be a daemon, but what's the best way to do that? It would be nice if I could just use Django's built in management functions rather than having one off scripts. i.e:
python manage.py linkconsumer
I would run that once when I started up the server and be good to go. It turned out to be pretty easy with python-daemon. I threw together a quick class to handle it and you can get a copy of the DaemonCommand here. All it really does is create an interface for a daemon context and open it. When subclassing the DaemonCommand instead of calling handle use handle_daemon.
Carrot is the open source project that ties the two together, but was a little too complex. So for the purpose of keeping it simple stupid, I used Nathan Borror's Flopsy. Dead simple way to communicate with a queue.
If we put that together we accomplish our goal in 20 lines of code.
from daemonextension import DaemonCommand
from django.conf import settings
import os
class Command(DaemonCommand):
#Declare Daemon std.
stdout = os.path.join(settings.DIRNAME, "log/cubbyscott.out")
stderr = os.path.join(settings.DIRNAME, "log/cubbyscott.err")
pidfile = os.path.join(settings.DIRNAME, "pid/cb_link.err")
def handle_daemon(self, *args, **options):
from flopsy import Connection, Consumer
consumer = Consumer(connection=Connection())
consumer.declare(queue='links',
exchange='cubbyscott',
routing_key='importer', auto_delete=False)
def message_callback(message):
print 'Recieved: ' + message.body
consumer.channel.basic_ack(message.delivery_tag)
consumer.register(message_callback)
consumer.wait()
Have you seen celery? http://pypi.python.org/pypi/celery
What do you think is complex in carrot? it's basically the same interface.