I am managing a django instance behind nginx connected using fcgi (using the manage.py runfcgi command). Because the code is loaded into memory I can not reload new code without killing and restarting the django fcgi processes, thus stifling the live website. The restarting itself becomes manifest pretty quickly. But by killing the fcgi processes first some users' actions can get interrupted which isn't good. I am wondering how do i reload new code without ever leading to any interruption. Advices is going to be highly appreciated!
And So I went ahead and implemented Martin's suggestion. This is actually the party script I emerged with.
pid_file=/path/to/pidfile port_file=/path/to/port_file old_pid=`cat $pid_file` if [[ -f $port_file ]] then last_port=`cat $port_file` port_to_use=$(($last_port + 1)) else port_to_use=8000 fi # Totally reset so me don't increase forever if [[ $port_to_use -gt 8999 ]] then port_to_use=8000 fi sed -i "s/$old_port/$port_to_use/g" /path/to/nginx.conf python manage.py runfcgi host=127...1 port=$port_to_use maxchildren=5 maxspare=5 minspare=2 method=prefork pidfile=$pid_file echo $port_to_use > $port_file kill -HUP `cat /var/run/nginx.pid` echo "Sleeping for five seconds" sleep 5s echo "Killing old processes on $last_port, pid $old_pid" kill $old_pid
I'd begin a new fcgi process on the new port, alter the nginx configuration to make use of the brand new port, have nginx reload configuration (which is elegant), then eventually stop that old process (you should use netstat to discover once the last link with that old port is closed).
Alternatively, you are able to alter the fcgi implementation to fork a brand new process, close all electrical sockets within the child aside from the fcgi server socket, close the fcgi server socket in parent, professional a brand new django process within the child (which makes it make use of the fcgi server socket), and terminate parents process once all fcgi connections are closed. IOW, implement elegant restart for runfcgi.
I discovered this site while searching for an answer with this problem. Anything else unsuccessful, and so i looked to the source code :)
The answer appears to become easier. Django fcgi server uses flup, which handles the HUP signal the right way: it shuts lower, beautifully. So all you want do would be to:
send the HUP signal towards the fcgi server (the pidfile= argument of runserver will prove useful)
wait a little (flup enables children processes ten seconds, so wait a few more 15 appears like many)
sent the KILL signal towards the fcgi server, just just in case something blocked it
start the server again
There you have it.
You should use breeding rather than FastCGI
We finally found the correct means to fix this!
First send flup a HUP signal to signal a restart. Flup will do that to any or all of their children:
- shuts the socket that will stop inactive children
- transmits a INT signal
- waits ten seconds
- transmits a KILL signal
When all of the youngsters are gone it'll start brand new ones.
This works many of the time, with the exception that if your child is getting through a request when flup executes step
2 your server will die with
KeyboardInterrupt, giving the consumer a 500 error.
The answer would be to use a SIGINT handler - begin to see the page above for particulars. Simply disregarding SIGINT gives your process ten seconds to exit that is enough for many demands.