Joe
Joe

Reputation: 47609

What's the simplest way to get Django to trigger a request back to itself?

I have a Django function which takes a snapshot of one of the pages served up by the app. It does this by opening an HTTP connection to the app, from the app.

This is running as a management command at the moment, and it works fine. I want to trigger this when a model is saved, however, as I'm snapshotting data connected with the model. If I trigger the function from the model's save method then I get into the situation where the view code is triggering a request part-way through the request-response Django cycle, and urllib2 complains.

I think this may be because there's only a single thread on my django dev server. Even if this is the cause, I don't want my app to depend on having two threads available during a model save. I don't want to couple my code to the threaddedness of the server.

I think I need to do this asynchronously so that when a model is saved, and the request/response cycle is over, some agent kicks in and says 'you need to run this function'.

Possible solutions involve creating a thread (which I don't think is a particularly good idea) or using Celery (which might be over-kill because I'm only doing a small volume of work).

I thought of using signal handlers, but the model signal handlers all execute synchronously during the model's save method, and the request_finished signals don't contain the model that was changed in the view.

I could use a cron job that runs the management command, but that would introduce other complexity. What if the previous job hasn't completed yet? How to indicate that and in what context to store that semaphore?

The volume will be very low, as it's done via the admin interface. I can't hook into the admin interface though, as this would also be executing during the request/response.

Assuming my problem is that I need to trigger this function asynchronously, what's the simplest way do to this?

Upvotes: 3

Views: 401

Answers (2)

olivecoder
olivecoder

Reputation: 2914

I don't know if it is acceptable to you but a simple way is write it as script and run it in background from django application.

Upvotes: 0

dgel
dgel

Reputation: 16796

I would definitely recommend celery- there really is no better option. Using django-celery with the django database broker is extremely lightweight and doesn't require setting up any AMQP server- it uses the same database that django uses.

I've used this setup for multiple django projects with lightweight asynchronous needs and it's very simple and reliable.

In case you happen to be using upstart, I posted an example of an upstart script to automatically start your django-celery broker here.

Upvotes: 2

Related Questions