screeley.com

Django Daemon Command Extension

June7

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()

Comments

Have you seen celery? http://pypi.python.org/pypi/celery

What do you think is complex in carrot? it's basically the same interface.

@Ask. celery looks awesome. I'll be playing with that today.

My issue with carrot was declaring queues and the lack of documentation. I don't have a lot of patience when it comes to that.

celery looks like it solves both those problems. Send me an email, would like to talk to you about it. sean@screeley.com

@sean I don't know if you've followed carrot recently, but after Nathan's blog post we've started documenting carrot, and it's really come a long way. See: http://ask.github.com/carrot/index.html Any comments/critique on the documentation is more than welcome.

carrot was originally just a part of celery, but seems to be useful on its own. Of course, py-amqplib is really what binds all this together, but I feel we need a common, tested, library, solving common messaging tasks as well.

I'll send you an e-mail.

I'm a developer out of San Francisco CA working at a startup.

This space will deal with the work I've participated in using the Django framework to build applications for enterprise clients.

Finally, you should follow me on twitter.

Ruminations

  • "generic z-pak <a href=http://sefsa.org>buy azithromycin</a>"
    at 7:53p.m. Aug. 27, 2010 | permalink

  • "How do i come up with cash from online gambling? <img>http://shrtn.info/smile/ref.php</img>"
    at 2:50a.m. Aug. 25, 2010 | permalink

  • "http://needman.ru замуж за иностранца <a href=http://needman.ru>знакомства с иностранцами</a>"
    at 12:59p.m. May 18, 2010 | permalink

  • "Yebhewjw <a href="http://yebhewjw.de">yebhewjw</a> http://yebhewjw.de yebhewjw http://yebhewjw.de"
    at 11:41p.m. April 29, 2010 | permalink

  • "Thanks for this, unbelievable our developer has a robots no follow tag on our site, no wonder it wasn't being found by the search engines ..."
    at 7:40a.m. March 2, 2010 | permalink

  • "maybe you are right. but how often robots.txt is actually accessed? and how much overhead there is? I'm curious - quantitatively - how big of ..."
    at 7:13p.m. Dec. 12, 2009 | permalink

  • "Lovely idea! Thanks for sharing. I'm gonna have a closer look at the patch for Django 1.2. This could help switching template engines a lot. ..."
    at 9:14a.m. Nov. 2, 2009 | permalink

  • "That was an inspiring post, I think Drupal is great! how could you hate it so much, Thanks for writing, most people don't bother."
    at 11:14a.m. Oct. 28, 2009 | permalink

  • "@Evgeniy. Yes at: http://code.google.com/p/django-alfresco/"
    at 10:42a.m. Oct. 22, 2009 | permalink

  • "Is this released as an open source project?"
    at 1:21a.m. Oct. 22, 2009 | permalink

  • "Interesting, thanks for the examples that you have shared, these are great... Anyway, thanks for the post"
    at 7:55a.m. Oct. 16, 2009 | permalink

  • "Quite inspiring, looks pretty easy aswell, as you have laid it out in such a way, great work, keep it up Thanks for bringing this ..."
    at 10:01a.m. Oct. 8, 2009 | permalink