tags:

views:

77

answers:

3

Hi,

I am working on a django web application.

A function 'xyx' (it updates a variable) needs to be called every 2 minutes.

I want one http request should start the daemon and keep calling xyz (every 2 minutes) until I send another http request to stop it.

Appreciate your ideas.

Thanks Vishal Rana

+4  A: 

There are a number of ways to achieve this. Assuming the correct server resources I would write a python script that calls function xyz "outside" of your django directory (although importing the necessary stuff) that only runs if /var/run/django-stuff/my-daemon.run exists. Get cron to run this every two minutes.

Then, for your django functions, your start function creates the above mentioned file if it doesn't already exist and the stop function destroys it.

As I say, there are other ways to achieve this. You could have a python script on loop waiting for approx 2 minutes... etc. In either case, you're up against the fact that two python scripts run on two different invocations of cpython (no idea if this is the case with mod_wsgi) cannot communicate with each other and as such IPC between python scripts is not simple, so you need to use some sort of formal IPC (like semaphores, files etc) rather than just common variables (which won't work).

Ninefingers
+1 a minute before me:(
puddingfox
+1 to using cron instead of trying to do it on django
nosklo
you can combine the two, cron + django custom management commands http://docs.djangoproject.com/en/dev/howto/custom-management-commands/
eos87
It will be a different process, I need to update a global variable inside 'xyz' residing in the running django app's memory.
Vishal
You'll need IPC in that case. The "daemon" process will be entirely separate to the django one, so you're better off grabbing said variable, perhaps via a file, when the "retrieve" function is called in django. An alternative to that has been posted below which sounds very good. Unfortunately there is no direct way (xyz using global var) to do this.
Ninefingers
+2  A: 

Probably a little hacked but you could try this:

Set up a crontab entry that runs a script every two minutes. This script will check for some sort of flag (file existence, contents of a file, etc.) on the disk to decide whether to run a given python module. The problem with this is it could take up to 1:59 to run the function the first time after it is started.

I think if you started a daemon in the view function it would keep the httpd worker process alive as well as the connection unless you figure out how to send a connection close without terminating the django view function. This could be very bad if you want to be able to do this in parallel for different users. Also to kill the function this way, you would have to somehow know which python and/or httpd process you want to kill later so you don't kill all of them.

The real way to do it would be to code an actual daemon in w/e language and just make a system call to "/etc/init.d/daemon_name start" and "... stop" in the django views. For this, you need to make sure your web server user has permission to execute the daemon.

puddingfox
+2  A: 

If the easy solutions (loop in a script, crontab signaled by a temp file) are too fragile for your intended usage, you could use Twisted facilities for process handling and scheduling and networking. Your Django app (using a Twisted client) would simply communicate via TCP (locally) with the Twisted server.

Vinko Vrsalovic
+1, not a bad idea at all.
Ninefingers