[Django]-Gunicorn, Django, and slow loading code…?

4👍

Gunicorn has some pretty awesome configuration. Was browsing around a git clone of their source and found an example_config.py which has a “post_fork” which got me thinking. After some poking around the source a bit more, I came up with this solution.

% gunicorn_django -c path/to/gunicorn_conf.py path/to/settings.py

Where gunicorn_conf.py has this function:

def post_fork(server, worker):
    server.log.info("%s: Worker spawned" % worker.pid)

    from gunicorn.workers.sync import SyncWorker
    class SyncWorkerPreload(SyncWorker):
        def run(self):
            pass

        def init_process(self):
            super(SyncWorkerPreload, self).init_process()
            from django.db.models.loading import get_apps
            get_apps()
            server.log.info('%s: App loaded' % self.pid)
            super(SyncWorkerPreload, self).run()

    worker.__class__ = SyncWorkerPreload

Hope that helps someone google’ing to find this hint.

Pretty awesome that Gunicorn was flexible enough to allow for this!

UPDATE: updated code, simply loading modules in settings sometimes breaks due to the way django loads modules I assume… this new code monkey patches gunicorn to load the modules at a “safe” time… hopefully

UPDATE: gunicorn 0.12.1 fixes this issue

0👍

This does sound like it’s due to Django’s delayed imports on some modules. I’d either go with settings.py or maybe the specific app’s urls.py to get them imported when the worker boots.

Leave a comment