[IMP] gunicorn: add CPU and memory limits.
[odoo/odoo.git] / gunicorn.conf.py
1 # Gunicorn sample configuration file.
2 # See http://gunicorn.org/configure.html for more details.
3 #
4 # To run OpenERP via Gunicorn, change the appropriate
5 # settings below, in order to provide the parameters that
6 # would normally be passed in the command-line,
7 # (at least `bind` and `conf['addons_path']`), then execute:
8 #  $ gunicorn openerp:wsgi.application -c gunicorn.conf.py
9
10 import openerp
11
12 # Standard OpenERP XML-RPC port is 8069
13 bind = '127.0.0.1:8069'
14
15 pidfile = '.gunicorn.pid'
16
17 # Gunicorn recommends 2-4 x number_of_cpu_cores, but
18 # you'll want to vary this a bit to find the best for your
19 # particular work load.
20 workers = 1
21
22 # Some application-wide initialization is needed.
23 on_starting = openerp.wsgi.on_starting
24 when_ready = openerp.wsgi.when_ready
25
26 # openerp request-response cycle can be quite long for
27 # big reports for example
28 timeout = 240
29
30 #max_requests = 150
31
32 # Equivalent of --load command-line option
33 openerp.conf.server_wide_modules = ['web']
34
35 # internal TODO: use openerp.conf.xxx when available
36 conf = openerp.tools.config
37
38 # Path to the OpenERP Addons repository (comma-separated for
39 # multiple locations)
40 conf['addons_path'] = '/home/thu/repos/addons/trunk,/home/thu/repos/web/trunk/addons,/home/thu/repos/server/trunk-limits/openerp/tests/addons'
41
42 # Optional database config if not using local socket
43 #conf['db_name'] = 'mycompany'
44 #conf['db_host'] = 'localhost'
45 #conf['db_user'] = 'foo'
46 #conf['db_port'] = 5432
47 #conf['db_password'] = 'secret'
48
49 # OpenERP Log Level
50 # DEBUG=10, DEBUG_RPC=8, DEBUG_RPC_ANSWER=6, DEBUG_SQL=5, INFO=20,
51 # WARNING=30, ERROR=40, CRITICAL=50
52 # conf['log_level'] = 20
53
54 # If --static-http-enable is used, path for the static web directory
55 #conf['static_http_document_root'] = '/var/www'
56
57 def time_expired(n, stack):
58     import os
59     import time
60     print '>>> [%s] time ran out.' % (os.getpid())
61     raise Exception('(time ran out)')
62
63 def pre_request(worker, req):
64     import os
65     import psutil
66     import resource
67     import signal
68     # VMS and RLIMIT_AS are the same thing: virtual memory, a.k.a. address space
69     rss, vms = psutil.Process(os.getpid()).get_memory_info()
70     soft, hard = resource.getrlimit(resource.RLIMIT_AS)
71     print ">>>>>> [%s] %s %s %s %s %s" % (os.getpid(), vms, req.method, req.path, req.query, req.fragment)
72     print ">>>>>>   %s" % (req.body,)
73     # Let's say 512MB is ok, 768 is a hard limit (will raise MemoryError),
74     # 640 will nicely restart the process.
75     resource.setrlimit(resource.RLIMIT_AS, (768 * 1024 * 1024, hard))
76     if vms > 640 * 1024 * 1024:
77         print ">>> Worker eating too much memory, reset it after the request."
78         worker.alive = False # Commit suicide after the request.
79
80     r = resource.getrusage(resource.RUSAGE_SELF)
81     cpu_time = r.ru_utime + r.ru_stime
82     signal.signal(signal.SIGXCPU, time_expired)
83     soft, hard = resource.getrlimit(resource.RLIMIT_CPU)
84     resource.setrlimit(resource.RLIMIT_CPU, (cpu_time + 15, hard))
85
86 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: