tags:

views:

68

answers:

4

In my Django app, I need to implement this "timer-based" functionality:

  1. User creates some jobs and for each one defines when (in the same unit the timer works, probably seconds) it will take place.
  2. User starts the timer.
  3. User may pause and resume the timer whenever he wants.
  4. A job is executed when its time is due.

This does not fit a typical cron scenario as time of execution is tied to a timer that the user can start, pause and resume.

What is the preferred way of doing this?

+1  A: 

This isn't a Django question. It is a system architecture problem. The http is stateless, so there is no notion of times.

My suggestion is to use Message Queues such as RabbitMQ and use Carrot to interface with it. You can put the jobs on the queue, then create a seperate consumer daemon which will process jobs from the queue. The consumer has the logic about when to process.

If that it too complex a system, perhaps look at implementing the timer in JS and having it call a url mapped to a view that processes a unit of work. The JS would be the timer.

ashchristopher
Thanks for the answer. You are of course right about http having no notion of time, however I see it a Django question in this sense: I want to know how Django developers solve similar problems. BTW, the introduction page to celery, the distributed task queue, says it was created for Django in the first place.
shanyu
A: 

You're going to end up with separate (from the web server) processes to monitor the queue and execute jobs. Consider how you would build that without Django using command-line tools to drive it. Use Django models to access the the database.

When you have that working, layer on on a web-based interface (using full Django) to manipulate the queue and report on job status.

I think that if you approach it this way the problem becomes much easier.

Dave W. Smith
Dave, thanks. I agree 100% with you on the basics, but I hope someone can provide more concrete suggestions about the implementation :)
shanyu
A: 

Have a look at Pinax, especially the notifications.

Once created they are pushed to the DB (queue), and processed by the cron-jobbed email-sending (2. consumer).

In this senario you won't stop it once it get fired. That could be managed by som (ajax-)views, that call system process....

edit

instead of cron-jobs you could use a twisted-based consumer:

  • write jobs to db with time-information to the db

  • send a request for consuming (or resuming, pausing, ...) to the twisted server via socket

  • do the rest in twisted

vikingosegundo
Thanks. I also have a similar mechanism for notifications. However in my scenario I can't use cron as cron is based on "real" time whereas I need a "fake" time, a counter which the user is free to start/pause/resume. Just like this: "Do job A after 100 secs, do job B after 200 secs. Pause everything if I pause the timer".
shanyu
Suggesting twisted is promising, thank you for that. I'll take a look at twisted and also celery in the coming days. Will keep you posted.
shanyu
A: 

I used the probably simplest (crudest is more appropriate, I'm afraid) approach possible: 1. Wrote a model featuring the current position and the state of the counter (active, paused, etc), 2. A django job that increments the counter if its state is active, 3. An entry to the cron that executes the job every minute.

Thanks everyone for the answers.

shanyu