# -*- coding: utf-8 -*-
##############################################################################
-#
+#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>).
+# Copyright (C) 2010-2012 OpenERP SA (<http://www.openerp.com>)
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# 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 <http://www.gnu.org/licenses/>.
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
-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
low-level behavior of the wire.
"""
-# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
+_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()
+
+ # Export (for RPC) services.
+ web_services.start_service()
+
+ 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.
+ cron.start_service()
+
+def stop_services():
+ """ 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
+ # 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).
+ me = threading.currentThread()
+ _logger.debug('current thread: %r', me)
+ for thread in threading.enumerate():
+ _logger.debug('process %r (%r)', thread, thread.isDaemon())
+ if thread != me and not thread.isDaemon() and thread.ident != main_thread_id:
+ while thread.isAlive():
+ _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()
+
+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: