1 # -*- coding: utf-8 -*-
2 ##############################################################################
4 # OpenERP, Open Source Management Solution
5 # Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>).
6 # Copyright (C) 2010-2013 OpenERP SA (<http://www.openerp.com>)
8 # This program is free software: you can redistribute it and/or modify
9 # it under the terms of the GNU Affero General Public License as
10 # published by the Free Software Foundation, either version 3 of the
11 # License, or (at your option) any later version.
13 # This program is distributed in the hope that it will be useful,
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 # GNU Affero General Public License for more details.
18 # You should have received a copy of the GNU Affero General Public License
19 # along with this program. If not, see <http://www.gnu.org/licenses/>.
21 ##############################################################################
35 import openerp.modules
38 from openerp.release import nt_service_name
40 from openerp.tools.misc import stripped_sys_argv
47 #.apidoc title: RPC Services
49 """ Classes of this module implement the network protocols that the
50 OpenERP server uses to communicate with remote clients.
52 Some classes are mostly utilities, whose API need not be visible to
53 the average user/developer. Study them only if you are about to
54 implement an extension to the network protocols, or need to debug some
55 low-level behavior of the wire.
58 _logger = logging.getLogger(__name__)
60 def load_server_wide_modules():
61 for m in openerp.conf.server_wide_modules:
63 openerp.modules.module.load_openerp_module(m)
68 The `web` module is provided by the addons found in the `openerp-web` project.
69 Maybe you forgot to add those addons in your addons_path configuration."""
70 _logger.exception('Failed to load server-wide module `%s`.%s', m, msg)
72 start_internal_done = False
73 main_thread_id = threading.currentThread().ident
76 global start_internal_done
77 if start_internal_done:
79 openerp.netsvc.init_logger()
81 load_server_wide_modules()
82 start_internal_done = True
85 """ Start all services including http, and cron """
87 # Start the WSGI server.
88 wsgi_server.start_service()
89 # Start the main cron thread.
90 if not openerp.evented:
94 """ Stop all services. """
96 if not openerp.evented:
98 wsgi_server.stop_service()
100 _logger.info("Initiating shutdown")
101 _logger.info("Hit CTRL-C again or send a second signal to force the shutdown.")
103 # Manually join() all threads before calling sys.exit() to allow a second signal
104 # to trigger _force_quit() in case some non-daemon threads won't exit cleanly.
105 # threading.Thread.join() should not mask signals (at least in python 2.5).
106 me = threading.currentThread()
107 _logger.debug('current thread: %r', me)
108 for thread in threading.enumerate():
109 _logger.debug('process %r (%r)', thread, thread.isDaemon())
110 if thread != me and not thread.isDaemon() and thread.ident != main_thread_id:
111 while thread.isAlive():
112 _logger.debug('join and sleep')
113 # Need a busyloop here as thread.join() masks signals
114 # and would prevent the forced shutdown.
119 openerp.modules.registry.RegistryManager.delete_all()
122 def start_services_workers():
123 import openerp.service.workers
124 openerp.multi_process = True
125 openerp.service.workers.Multicorn(openerp.service.wsgi_server.application).run()
128 """reexecute openerp-server process with (nearly) the same arguments"""
129 if openerp.tools.osutil.is_running_as_nt_service():
130 subprocess.call('net stop {0} && net start {0}'.format(nt_service_name), shell=True)
131 exe = os.path.basename(sys.executable)
132 args = stripped_sys_argv()
133 if not args or args[0] != exe:
135 os.execv(sys.executable, args)
137 def restart_server():
138 if openerp.multi_process:
139 raise NotImplementedError("Multicorn is not supported (but gunicorn was)")
140 pid = openerp.wsgi.core.arbiter_pid
141 os.kill(pid, signal.SIGHUP)
148 # run in a thread to let the current thread return response to the caller.
149 threading.Thread(target=reborn).start()
151 openerp.phoenix = True
152 os.kill(os.getpid(), signal.SIGINT)
154 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: