1 # -*- coding: utf-8 -*-
2 ##############################################################################
4 # OpenERP, Open Source Management Solution
5 # Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>).
7 # This program is free software: you can redistribute it and/or modify
8 # it under the terms of the GNU Affero General Public License as
9 # published by the Free Software Foundation, either version 3 of the
10 # License, or (at your option) any later version.
12 # This program is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU Affero General Public License for more details.
17 # You should have received a copy of the GNU Affero General Public License
18 # along with this program. If not, see <http://www.gnu.org/licenses/>.
20 ##############################################################################
33 import openerp.modules
37 import openerp.service.wsgi_server
39 #.apidoc title: RPC Services
41 """ Classes of this module implement the network protocols that the
42 OpenERP server uses to communicate with remote clients.
44 Some classes are mostly utilities, whose API need not be visible to
45 the average user/developer. Study them only if you are about to
46 implement an extension to the network protocols, or need to debug some
47 low-level behavior of the wire.
50 _logger = logging.getLogger(__name__)
52 def load_server_wide_modules():
53 for m in openerp.conf.server_wide_modules:
55 openerp.modules.module.load_openerp_module(m)
60 The `web` module is provided by the addons found in the `openerp-web` project.
61 Maybe you forgot to add those addons in your addons_path configuration."""
62 _logger.exception('Failed to load server-wide module `%s`.%s', m, msg)
64 start_internal_done = False
67 global start_internal_done
68 if start_internal_done:
70 openerp.netsvc.init_logger()
71 openerp.modules.loading.open_openerp_namespace()
72 # Instantiate local services (this is a legacy design).
73 openerp.osv.osv.start_object_proxy()
74 # Export (for RPC) services.
75 web_services.start_web_services()
76 load_server_wide_modules()
77 start_internal_done = True
80 """ Start all services including http, netrpc and cron """
83 # Initialize the HTTP stack.
84 netrpc_server.init_servers()
86 # Start the main cron thread.
87 if openerp.conf.max_cron_threads:
88 openerp.cron.start_master_thread()
90 # Start the top-level servers threads (normally HTTP, HTTPS, and NETRPC).
91 openerp.netsvc.Server.startAll()
93 # Start the WSGI server.
94 openerp.service.wsgi_server.start_server()
97 """ Stop all services. """
98 # stop scheduling new jobs; we will have to wait for the jobs to complete below
99 openerp.cron.cancel_all()
101 openerp.netsvc.Server.quitAll()
102 openerp.service.wsgi_server.stop_server()
103 _logger.info("Initiating shutdown")
104 _logger.info("Hit CTRL-C again or send a second signal to force the shutdown.")
106 # Manually join() all threads before calling sys.exit() to allow a second signal
107 # to trigger _force_quit() in case some non-daemon threads won't exit cleanly.
108 # threading.Thread.join() should not mask signals (at least in python 2.5).
109 me = threading.currentThread()
110 _logger.debug('current thread: %r', me)
111 for thread in threading.enumerate():
112 _logger.debug('process %r (%r)', thread, thread.isDaemon())
113 if thread != me and not thread.isDaemon():
114 while thread.isAlive():
115 _logger.debug('join and sleep')
116 # Need a busyloop here as thread.join() masks signals
117 # and would prevent the forced shutdown.
122 openerp.modules.registry.RegistryManager.delete_all()
125 def start_services_workers():
126 import openerp.service.workers
127 openerp.multi_process = True
128 openerp.service.workers.Multicorn(openerp.service.wsgi_server.application).run()
131 """reexecute openerp-server process with (nearly) the same arguments"""
132 # TODO check if parent is a NT service
133 strip_args = ['-d', '-u']
135 args = [x for i, x in enumerate(a) if x not in strip_args and a[max(i - 1, 0)] not in strip_args]
136 os.execv(sys.executable, [sys.executable] + args)
138 def restart_server():
139 if openerp.multi_process:
140 raise NotImplementedError("Multicorn is not supported (but gunicorn was)")
141 pid = openerp.wsgi.core.arbiter_pid
142 os.kill(pid, signal.SIGHUP)
149 # run in a thread to let the current thread return response to the caller.
150 threading.Thread(target=reborn).start()
152 openerp.phoenix = True
153 os.kill(os.getpid(), signal.SIGINT)
155 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: