среда, 10 сентября 2014 г.

buildout gunicorn gevent django 1.7

After upgrading from django 1.5.5 to django 1.7 i couldn't make gunicorn work. It kept telling me (when running bin/django run_gunicorn -c config/gunicorn)
HaltServer Worker failed to boot: 3
and
bin/django runserver
works fine.

After some time I've got working solution for my case. I took code http://gunicorn-docs.readthedocs.org/en/latest/custom.html

As you can see at L06 I have parse func. I am using buildout, which creates django and django.wsgi files in bin/ directory. And in these files sys.path is changed to make your app be able to locate eggs, which are located in eggs/ dir. (e.g. eggs/Django-1.7-py2.7.egg). So gevent is also located there (eggs/gevent-1.0.1-py2.7-linux-x86_64.egg) in my case. So I have to change sys.path, then I do monkey patching with gevent and then with gevent_psycopg2 since I'm using postgresql.


#!/usr/bin/python

from __future__ import unicode_literals
import sys

def parse():
    s = False
    result = []
    with open("bin/django.wsgi", "r") as f:
        for line in f.readlines():
            if line.startswith("sys.path[0:0]"):
                s = True
                continue
            if "]" in line:
                break
            if s:
                result.append(line.strip()[1:-2])
    return result

sys.path[0:0] = parse()

import gevent.monkey
gevent.monkey.patch_all()

import gevent_psycopg2
gevent_psycopg2.monkey_patch()


import multiprocessing

import gunicorn.app.base

from gunicorn.six import iteritems

def number_of_workers():
    return (multiprocessing.cpu_count() * 2) + 1


class StandaloneApplication(gunicorn.app.base.BaseApplication):

    def __init__(self, app, options=None):
        self.options = options or {}
        self.application = app
        super(StandaloneApplication, self).__init__()

    def load_config(self):
        config = dict([(key, value) for key, value in iteritems(self.options)
                       if key in self.cfg.settings and value is not None])
        for key, value in iteritems(config):
            self.cfg.set(key.lower(), value)

    def load(self):
        return self.application


if __name__ == '__main__':
    options = {
        'bind': '%s:%s' % ('0.0.0.0', '8000'),
        'workers': number_of_workers(),
        'worker_class': "gunicorn.workers.ggevent.GeventWorker",
        'debug': True
    }
    import djangorecipe.wsgi

    application = djangorecipe.wsgi.main('homecont.development', logfile='')
    StandaloneApplication(application, options).run()

Комментариев нет:

Отправить комментарий