[MERGE] forward port of branch 7.0 up to revid 4067 chs@openerp.com-20131114142639...
[odoo/odoo.git] / openerpcommand / web.py
1 """
2 Run a normal OpenERP HTTP process.
3 """
4
5 import logging
6 import os
7 import signal
8
9 import common
10
11 _logger = logging.getLogger(__name__)
12
13 def mk_signal_handler(server):
14     def signal_handler(sig, frame):
15         """
16         Specialized signal handler for the evented process.
17         """
18         print "\n\n\nStopping gevent HTTP server...\n\n\n"
19         server.stop()
20     return signal_handler
21
22 def setup_signal_handlers(signal_handler):
23     SIGNALS = (signal.SIGINT, signal.SIGTERM)
24     map(lambda sig: signal.signal(sig, signal_handler), SIGNALS)
25
26 def run(args):
27     # Note that gevent monkey patching must be done before importing the
28     # `threading` module, see http://stackoverflow.com/questions/8774958/.
29     if args.gevent:
30         import gevent
31         import gevent.monkey
32         import gevent.wsgi
33         import gevent_psycopg2
34         gevent.monkey.patch_all()
35         gevent_psycopg2.monkey_patch()
36     import threading
37     import openerp
38     import openerp.cli.server
39     import openerp.service.wsgi_server
40     import openerp.tools.config
41     config = openerp.tools.config
42
43     os.environ["TZ"] = "UTC"
44     common.set_addons(args)
45
46     openerp.multi_process = True
47     common.setproctitle('openerp-web')
48
49     openerp.cli.server.check_root_user()
50     openerp.netsvc.init_logger()
51     #openerp.cli.server.report_configuration()
52
53     target = openerp.service.wsgi_server.serve
54     if not args.gevent:
55         openerp.evented = False
56         openerp.cli.server.setup_signal_handlers(openerp.cli.server.signal_handler)
57         # TODO openerp.multi_process with a multi-threaded process probably
58         # doesn't work very well (e.g. waiting for all threads to complete
59         # before killing the process is not implemented).
60         arg = (args.interface, int(args.port), args.threaded)
61         threading.Thread(target=target, args=arg).start()
62         openerp.cli.server.quit_on_signals()
63     else:
64         openerp.evented = True
65
66         app = openerp.service.wsgi_server.application
67         server = gevent.wsgi.WSGIServer((args.interface, int(args.port)), app)
68         setup_signal_handlers(mk_signal_handler(server))
69         try:
70             server.serve_forever()
71         except KeyboardInterrupt:
72             try:
73                 server.stop()
74                 gevent.shutdown()
75             except KeyboardInterrupt:
76                 sys.stderr.write("Forced shutdown.\n")
77                 gevent.shutdown()
78
79 def add_parser(subparsers):
80     parser = subparsers.add_parser('web',
81         description='Run a normal OpenERP HTTP process. By default a '
82         'singly-threaded Werkzeug server is used.')
83     common.add_addons_argument(parser)
84     parser.add_argument('--interface', default='0.0.0.0',
85         help='HTTP interface to listen on (default is %(default)s)')
86     parser.add_argument('--port', metavar='INT', default=8069,
87         help='HTTP port to listen on (default is %(default)s)')
88     parser.add_argument('--threaded', action='store_true',
89         help='Use a multithreaded Werkzeug server (incompatible with --gevent)')
90     parser.add_argument('--gevent', action='store_true',
91         help="Use gevent's WSGI server (incompatible with --threaded)")
92
93     parser.set_defaults(run=run)