Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

mod_wsgi force reload modules

Is there a way to have mod_wsgi reload all modules (maybe in a particular directory) on each load?

While working on the code, it's very annoying to restart apache every time something is changed. The only option I've found so far is to put modname = reload(modname) below every import.. but that's also really annoying since it means I'm going to have to go through and remove them all at a later date..

like image 336
Ian Avatar asked Apr 20 '09 02:04

Ian


4 Answers

The link:

http://code.google.com/p/modwsgi/wiki/ReloadingSourceCode

should be emphasised. It also should be emphaised that on UNIX systems daemon mode of mod_wsgi must be used and you must implement the code monitor described in the documentation. The whole process reloading option will not work for embedded mode of mod_wsgi on UNIX systems. Even though on Windows systems the only option is embedded mode, it is possible through a bit of trickery to do the same thing by triggering an internal restart of Apache from the code monitoring script. This is also described in the documentation.

like image 149
Graham Dumpleton Avatar answered Sep 21 '22 16:09

Graham Dumpleton


The following solution is aimed at Linux users only, and has been tested to work under Ubuntu Server 12.04.1

To run WSGI under daemon mode, you need to specify WSGIProcessGroup and WSGIDaemonProcess directives in your Apache configuration file, for example

WSGIProcessGroup my_wsgi_process
WSGIDaemonProcess my_wsgi_process threads=15

More details are available in http://code.google.com/p/modwsgi/wiki/ConfigurationDirectives

An added bonus is extra stability if you are running multiple WSGI sites under the same server, potentially with VirtualHost directives. Without using daemon processes, I found two Django sites conflicting with each other and turning up 500 Internal Server Error's alternatively.

At this point, your server is in fact already monitoring your WSGI site for changes, though it only watches the file you specified using WSGIScriptAlias, like

WSGIScriptAlias / /var/www/my_django_site/my_django_site/wsgi.py

This means that you can force the WSGI daemon process to reload by changing the WSGI script. Of course, you don't have to change its contents, but rather,

$ touch /var/www/my_django_site/my_django_site/wsgi.py

would do the trick.

By utilizing the method above, you can automatically reload a WSGI site in production environment without restarting/reloading the entire Apache server, or modifying your WSGI script to do production-unsafe code change monitoring.

This is particularly useful when you have automated deploy scripts, and don't want to restart the Apache server on deployment.

During development, you may use a filesystem changes watcher to invoke touch wsgi.py every time a module under your site changes, for example, pywatch

like image 36
Interarticle Avatar answered Sep 19 '22 16:09

Interarticle


The mod_wsgi documentation on code reloading is your best bet for an answer.

like image 41
Ignacio Vazquez-Abrams Avatar answered Sep 18 '22 16:09

Ignacio Vazquez-Abrams


I know it's an old thread but this might help someone. To kill your process when any file in a certain directory is written to, you can use something like this:

monitor.py

import os, sys, time, signal, threading, atexit
import inotify.adapters

def _monitor(path):

    i = inotify.adapters.InotifyTree(path)

    print "monitoring", path
    while 1:
        for event in i.event_gen():
            if event is not None:
                (header, type_names, watch_path, filename) = event
                if 'IN_CLOSE_WRITE' in type_names:
                    prefix = 'monitor (pid=%d):' % os.getpid()
                    print "%s %s/%s changed," % (prefix, path, filename), 'restarting!'
                    os.kill(os.getpid(), signal.SIGKILL)

def start(path):

    t = threading.Thread(target = _monitor, args = (path,))
    t.setDaemon(True)
    t.start()

    print 'Started change monitor. (pid=%d)' % os.getpid()

In your server startup, call it like:

server.py

import monitor

monitor.start(<directory which contains your wsgi files>)

if your main server file is in the directory which contains all your files, you can go like:

monitor.start(os.path.dirname(__file__))

Adding other folders is left as an exercise...

You'll need to 'pip install inotify'

This was cribbed from the code here: https://code.google.com/archive/p/modwsgi/wikis/ReloadingSourceCode.wiki#Restarting_Daemon_Processes

This is an answer to my duplicate question here: WSGI process reload modules

like image 23
Charlie Skilbeck Avatar answered Sep 18 '22 16:09

Charlie Skilbeck