netsvc, netrpc, wizardcleanup
[odoo/odoo.git] / openerp / service / __init__.py
1 # -*- coding: utf-8 -*-
2 ##############################################################################
3 #
4 #    OpenERP, Open Source Management Solution
5 #    Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>).
6 #    Copyright (C) 2010-2012 OpenERP SA (<http://www.openerp.com>)
7 #
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.
12 #
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.
17 #
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/>.
20 #
21 ##############################################################################
22
23 import logging
24 import threading
25 import time
26
27 import netrpc_server
28 import web_services
29
30 import openerp.cron
31 import openerp.modules
32 import openerp.netsvc
33 import openerp.osv
34 import openerp.tools
35 import openerp.service.wsgi_server
36
37 #.apidoc title: RPC Services
38
39 """ Classes of this module implement the network protocols that the
40     OpenERP server uses to communicate with remote clients.
41
42     Some classes are mostly utilities, whose API need not be visible to
43     the average user/developer. Study them only if you are about to
44     implement an extension to the network protocols, or need to debug some
45     low-level behavior of the wire.
46 """
47
48 _logger = logging.getLogger(__name__)
49
50 def load_server_wide_modules():
51     for m in openerp.conf.server_wide_modules:
52         try:
53             openerp.modules.module.load_openerp_module(m)
54         except Exception:
55             msg = ''
56             if m == 'web':
57                 msg = """
58 The `web` module is provided by the addons found in the `openerp-web` project.
59 Maybe you forgot to add those addons in your addons_path configuration."""
60             _logger.exception('Failed to load server-wide module `%s`.%s', m, msg)
61
62 start_internal_done = False
63 main_thread_id = threading.currentThread().ident
64
65 def start_internal():
66     global start_internal_done
67     if start_internal_done:
68         return
69     openerp.netsvc.init_logger()
70     openerp.modules.loading.open_openerp_namespace()
71     # Instantiate local services (this is a legacy design).
72     openerp.osv.osv.start_object_proxy()
73     # Export (for RPC) services.
74     web_services.start_web_services()
75     load_server_wide_modules()
76     start_internal_done = True
77
78 def start_services():
79     """ Start all services including http, netrpc and cron """
80     start_internal()
81
82     # Initialize the NETRPC server.
83     netrpc_server.init_servers()
84
85     # Start the main cron thread.
86     if openerp.conf.max_cron_threads:
87         openerp.cron.start_master_thread()
88
89     # Start the WSGI server.
90     openerp.service.wsgi_server.start_server()
91
92 def stop_services():
93     """ Stop all services. """
94     # stop scheduling new jobs; we will have to wait for the jobs to complete below
95     openerp.cron.cancel_all()
96
97     netrpc_server.Server.quitAll()
98     openerp.service.wsgi_server.stop_server()
99     _logger.info("Initiating shutdown")
100     _logger.info("Hit CTRL-C again or send a second signal to force the shutdown.")
101     logging.shutdown()
102
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     for thread in threading.enumerate():
108         if thread != me and not thread.isDaemon() and thread.ident != main_thread_id:
109             while thread.isAlive():
110                 # Need a busyloop here as thread.join() masks signals
111                 # and would prevent the forced shutdown.
112                 thread.join(0.05)
113                 time.sleep(0.05)
114
115     openerp.modules.registry.RegistryManager.delete_all()
116
117 def start_services_workers():
118     import openerp.service.workers
119     openerp.multi_process = True
120
121     openerp.service.workers.Multicorn(openerp.service.wsgi_server.application).run()
122
123
124 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: