X-Git-Url: http://git.inspyration.org/?a=blobdiff_plain;f=openerp%2Fservice%2F__init__.py;h=9f92134058679d88c00d55005f108212262aef19;hb=fc27a7b3a4ebabc586498ea2c91ccafde5b46a67;hp=2a4c03a08924e0474f3e479b87bb9d257be67e1a;hpb=cc26f2b5d2fb7e1046989541ba292190901b6276;p=odoo%2Fodoo.git diff --git a/openerp/service/__init__.py b/openerp/service/__init__.py index 2a4c03a..9f92134 100644 --- a/openerp/service/__init__.py +++ b/openerp/service/__init__.py @@ -1,8 +1,9 @@ # -*- coding: utf-8 -*- ############################################################################## -# +# # OpenERP, Open Source Management Solution # Copyright (C) 2004-2009 Tiny SPRL (). +# Copyright (C) 2010-2012 OpenERP SA () # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as @@ -15,13 +16,28 @@ # GNU Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . +# along with this program. If not, see . # ############################################################################## -import http_server -import netrpc_server +import logging +import os +import signal +import subprocess +import sys +import threading +import time + +import cron +import web_services import web_services +import wsgi_server + +import openerp.modules +import openerp.netsvc +import openerp.osv +from openerp.release import nt_service_name +import openerp.tools #.apidoc title: RPC Services @@ -34,52 +50,104 @@ import web_services low-level behavior of the wire. """ -def start_services(): - import openerp - http_server = openerp.service.http_server - netrpc_server = openerp.service.netrpc_server +_logger = logging.getLogger(__name__) + +def load_server_wide_modules(): + for m in openerp.conf.server_wide_modules: + try: + openerp.modules.module.load_openerp_module(m) + except Exception: + msg = '' + if m == 'web': + msg = """ +The `web` module is provided by the addons found in the `openerp-web` project. +Maybe you forgot to add those addons in your addons_path configuration.""" + _logger.exception('Failed to load server-wide module `%s`.%s', m, msg) + +start_internal_done = False +main_thread_id = threading.currentThread().ident + +def start_internal(): + global start_internal_done + if start_internal_done: + return + openerp.netsvc.init_logger() + openerp.modules.loading.open_openerp_namespace() - # Instantiate local services (this is a legacy design). - openerp.osv.osv.start_object_proxy() # Export (for RPC) services. - openerp.service.web_services.start_web_services() + web_services.start_service() - # Initialize the HTTP stack. - http_server.init_servers() - http_server.init_xmlrpc() - http_server.init_static_http() - netrpc_server.init_servers() + load_server_wide_modules() + start_internal_done = True +def start_services(): + """ Start all services including http, and cron """ + start_internal() + # Start the WSGI server. + wsgi_server.start_service() # Start the main cron thread. - openerp.netsvc.start_agent() - - # Start the top-level servers threads (normally HTTP, HTTPS, and NETRPC). - openerp.netsvc.Server.startAll() + cron.start_service() def stop_services(): - import openerp - import logging - import threading - import time - openerp.netsvc.Agent.quit() - openerp.netsvc.Server.quitAll() - config = openerp.tools.config - logger = logging.getLogger('server') - logger.info("Initiating shutdown") - logger.info("Hit CTRL-C again or send a second signal to force the shutdown.") - logging.shutdown() + """ Stop all services. """ + # stop services + cron.stop_service() + wsgi_server.stop_service() + + _logger.info("Initiating shutdown") + _logger.info("Hit CTRL-C again or send a second signal to force the shutdown.") - # manually join() all threads before calling sys.exit() to allow a second signal + # Manually join() all threads before calling sys.exit() to allow a second signal # to trigger _force_quit() in case some non-daemon threads won't exit cleanly. - # threading.Thread.join() should not mask signals (at least in python 2.5) + # threading.Thread.join() should not mask signals (at least in python 2.5). + me = threading.currentThread() + _logger.debug('current thread: %r', me) for thread in threading.enumerate(): - if thread != threading.currentThread() and not thread.isDaemon(): + _logger.debug('process %r (%r)', thread, thread.isDaemon()) + if thread != me and not thread.isDaemon() and thread.ident != main_thread_id: while thread.isAlive(): - # need a busyloop here as thread.join() masks signals - # and would present the forced shutdown + _logger.debug('join and sleep') + # Need a busyloop here as thread.join() masks signals + # and would prevent the forced shutdown. thread.join(0.05) time.sleep(0.05) + _logger.debug('--') + openerp.modules.registry.RegistryManager.delete_all() + logging.shutdown() -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: +def start_services_workers(): + import openerp.service.workers + openerp.multi_process = True + openerp.service.workers.Multicorn(openerp.service.wsgi_server.application).run() +def _reexec(): + """reexecute openerp-server process with (nearly) the same arguments""" + if openerp.tools.osutil.is_running_as_nt_service(): + subprocess.call('net stop {0} && net start {0}'.format(nt_service_name), shell=True) + exe = os.path.basename(sys.executable) + strip_args = ['-d', '-u'] + a = sys.argv[:] + args = [x for i, x in enumerate(a) if x not in strip_args and a[max(i - 1, 0)] not in strip_args] + if not args or args[0] != exe: + args.insert(0, exe) + os.execv(sys.executable, args) + +def restart_server(): + if openerp.multi_process: + raise NotImplementedError("Multicorn is not supported (but gunicorn was)") + pid = openerp.wsgi.core.arbiter_pid + os.kill(pid, signal.SIGHUP) + else: + if os.name == 'nt': + def reborn(): + stop_services() + _reexec() + + # run in a thread to let the current thread return response to the caller. + threading.Thread(target=reborn).start() + else: + openerp.phoenix = True + os.kill(os.getpid(), signal.SIGINT) + +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: