mirror of
https://github.com/bringout/oca-ocb-core.git
synced 2026-04-20 11:52:04 +02:00
18.0 vanilla
This commit is contained in:
parent
d72e748793
commit
0a7ae8db93
337 changed files with 399651 additions and 232598 deletions
|
|
@ -15,17 +15,12 @@ import subprocess
|
|||
import sys
|
||||
import threading
|
||||
import time
|
||||
import unittest
|
||||
import contextlib
|
||||
from email.utils import parsedate_to_datetime
|
||||
from io import BytesIO
|
||||
from itertools import chain
|
||||
|
||||
import psutil
|
||||
import werkzeug.serving
|
||||
from werkzeug.debug import DebuggedApplication
|
||||
|
||||
from ..tests import loader
|
||||
|
||||
if os.name == 'posix':
|
||||
# Unix only for workers
|
||||
|
|
@ -62,7 +57,8 @@ from odoo.modules import get_modules
|
|||
from odoo.modules.registry import Registry
|
||||
from odoo.release import nt_service_name
|
||||
from odoo.tools import config
|
||||
from odoo.tools import stripped_sys_argv, dumpstacks, log_ormcache_stats
|
||||
from odoo.tools.cache import log_ormcache_stats
|
||||
from odoo.tools.misc import stripped_sys_argv, dumpstacks
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
|
|
@ -81,10 +77,15 @@ def memory_info(process):
|
|||
|
||||
|
||||
def set_limit_memory_hard():
|
||||
if platform.system() == 'Linux' and config['limit_memory_hard']:
|
||||
if platform.system() != 'Linux':
|
||||
return
|
||||
limit_memory_hard = config['limit_memory_hard']
|
||||
if odoo.evented and config['limit_memory_hard_gevent']:
|
||||
limit_memory_hard = config['limit_memory_hard_gevent']
|
||||
if limit_memory_hard:
|
||||
rlimit = resource.RLIMIT_AS
|
||||
soft, hard = resource.getrlimit(rlimit)
|
||||
resource.setrlimit(rlimit, (config['limit_memory_hard'], hard))
|
||||
resource.setrlimit(rlimit, (limit_memory_hard, hard))
|
||||
|
||||
def empty_pipe(fd):
|
||||
try:
|
||||
|
|
@ -255,21 +256,7 @@ class ThreadedWSGIServerReloadable(LoggingBaseWSGIServerMixIn, werkzeug.serving.
|
|||
t.start_time = time.time()
|
||||
t.start()
|
||||
|
||||
# TODO: Remove this method as soon as either of the revision
|
||||
# - python/cpython@8b1f52b5a93403acd7d112cd1c1bc716b31a418a for Python 3.6,
|
||||
# - python/cpython@908082451382b8b3ba09ebba638db660edbf5d8e for Python 3.7,
|
||||
# is included in all Python 3 releases installed on all operating systems supported by Odoo.
|
||||
# These revisions are included in Python from releases 3.6.8 and Python 3.7.2 respectively.
|
||||
def _handle_request_noblock(self):
|
||||
"""
|
||||
In the python module `socketserver` `process_request` loop,
|
||||
the __shutdown_request flag is not checked between select and accept.
|
||||
Thus when we set it to `True` thanks to the call `httpd.shutdown`,
|
||||
a last request is accepted before exiting the loop.
|
||||
We override this function to add an additional check before the accept().
|
||||
"""
|
||||
if self._BaseServer__shutdown_request:
|
||||
return
|
||||
if self.max_http_threads and not self.http_threads_sem.acquire(timeout=0.1):
|
||||
# If the semaphore is full we will return immediately to the upstream (most probably
|
||||
# socketserver.BaseServer's serve_forever loop which will retry immediately as the
|
||||
|
|
@ -299,7 +286,7 @@ class FSWatcherBase(object):
|
|||
except SyntaxError:
|
||||
_logger.error('autoreload: python code change detected, SyntaxError in %s', path)
|
||||
else:
|
||||
if not getattr(odoo, 'phoenix', False):
|
||||
if not server_phoenix:
|
||||
_logger.info('autoreload: python code updated, autoreload activated')
|
||||
restart()
|
||||
return True
|
||||
|
|
@ -450,7 +437,8 @@ class ThreadedServer(CommonServer):
|
|||
os._exit(0)
|
||||
elif sig == signal.SIGHUP:
|
||||
# restart on kill -HUP
|
||||
odoo.phoenix = True
|
||||
global server_phoenix # noqa: PLW0603
|
||||
server_phoenix = True
|
||||
self.quit_signals_received += 1
|
||||
# interrupt run() to start shutdown
|
||||
raise KeyboardInterrupt()
|
||||
|
|
@ -557,14 +545,13 @@ class ThreadedServer(CommonServer):
|
|||
t.start()
|
||||
_logger.debug("cron%d started!" % i)
|
||||
|
||||
def http_thread(self):
|
||||
self.httpd = ThreadedWSGIServerReloadable(self.interface, self.port, self.app)
|
||||
self.httpd.serve_forever()
|
||||
|
||||
def http_spawn(self):
|
||||
t = threading.Thread(target=self.http_thread, name="odoo.service.httpd")
|
||||
t.daemon = True
|
||||
t.start()
|
||||
self.httpd = ThreadedWSGIServerReloadable(self.interface, self.port, self.app)
|
||||
threading.Thread(
|
||||
target=self.httpd.serve_forever,
|
||||
name="odoo.service.httpd",
|
||||
daemon=True,
|
||||
).start()
|
||||
|
||||
def start(self, stop=False):
|
||||
_logger.debug("Setting signal handlers")
|
||||
|
|
@ -589,7 +576,7 @@ class ThreadedServer(CommonServer):
|
|||
def stop(self):
|
||||
""" Shutdown the WSGI server. Wait for non daemon threads.
|
||||
"""
|
||||
if getattr(odoo, 'phoenix', None):
|
||||
if server_phoenix:
|
||||
_logger.info("Initiating server reload")
|
||||
else:
|
||||
_logger.info("Initiating shutdown")
|
||||
|
|
@ -630,13 +617,13 @@ class ThreadedServer(CommonServer):
|
|||
The first SIGINT or SIGTERM signal will initiate a graceful shutdown while
|
||||
a second one if any will force an immediate exit.
|
||||
"""
|
||||
self.start(stop=stop)
|
||||
|
||||
rc = preload_registries(preload)
|
||||
with Registry._lock:
|
||||
self.start(stop=stop)
|
||||
rc = preload_registries(preload)
|
||||
|
||||
if stop:
|
||||
if config['test_enable']:
|
||||
logger = odoo.tests.result._logger
|
||||
from odoo.tests.result import _logger as logger # noqa: PLC0415
|
||||
with Registry.registries._lock:
|
||||
for db, registry in Registry.registries.d.items():
|
||||
report = registry._assertion_report
|
||||
|
|
@ -671,7 +658,7 @@ class ThreadedServer(CommonServer):
|
|||
# `reload` increments `self.quit_signals_received`
|
||||
# and the loop will end after this iteration,
|
||||
# therefore leading to the server stop.
|
||||
# `reload` also sets the `phoenix` flag
|
||||
# `reload` also sets the `server_phoenix` flag
|
||||
# to tell the server to restart the server after shutting down.
|
||||
else:
|
||||
time.sleep(1)
|
||||
|
|
@ -697,7 +684,8 @@ class GeventServer(CommonServer):
|
|||
_logger.warning("Gevent Parent changed: %s", self.pid)
|
||||
restart = True
|
||||
memory = memory_info(psutil.Process(self.pid))
|
||||
if config['limit_memory_soft'] and memory > config['limit_memory_soft']:
|
||||
limit_memory_soft = config['limit_memory_soft_gevent'] or config['limit_memory_soft']
|
||||
if limit_memory_soft and memory > limit_memory_soft:
|
||||
_logger.warning('Gevent virtual memory limit reached: %s', memory)
|
||||
restart = True
|
||||
if restart:
|
||||
|
|
@ -891,7 +879,8 @@ class PreforkServer(CommonServer):
|
|||
raise KeyboardInterrupt
|
||||
elif sig == signal.SIGHUP:
|
||||
# restart on kill -HUP
|
||||
odoo.phoenix = True
|
||||
global server_phoenix # noqa: PLW0603
|
||||
server_phoenix = True
|
||||
raise KeyboardInterrupt
|
||||
elif sig == signal.SIGQUIT:
|
||||
# dump stacks on kill -3
|
||||
|
|
@ -1308,6 +1297,7 @@ class WorkerCron(Worker):
|
|||
#----------------------------------------------------------
|
||||
|
||||
server = None
|
||||
server_phoenix = False
|
||||
|
||||
def load_server_wide_modules():
|
||||
server_wide_modules = list(odoo.conf.server_wide_modules)
|
||||
|
|
@ -1336,9 +1326,11 @@ def _reexec(updated_modules=None):
|
|||
# We should keep the LISTEN_* environment variabled in order to support socket activation on reexec
|
||||
os.execve(sys.executable, args, os.environ)
|
||||
|
||||
|
||||
def load_test_file_py(registry, test_file):
|
||||
# pylint: disable=import-outside-toplevel
|
||||
from odoo.tests.suite import OdooSuite
|
||||
from odoo.tests import loader # noqa: PLC0415
|
||||
from odoo.tests.suite import OdooSuite # noqa: PLC0415
|
||||
threading.current_thread().testing = True
|
||||
try:
|
||||
test_path, _ = os.path.splitext(os.path.abspath(test_file))
|
||||
|
|
@ -1346,8 +1338,7 @@ def load_test_file_py(registry, test_file):
|
|||
for mod_mod in loader.get_test_modules(mod):
|
||||
mod_path, _ = os.path.splitext(getattr(mod_mod, '__file__', ''))
|
||||
if test_path == config._normalize(mod_path):
|
||||
tests = loader.unwrap_suite(
|
||||
unittest.TestLoader().loadTestsFromModule(mod_mod))
|
||||
tests = loader.get_module_test_cases(mod_mod)
|
||||
suite = OdooSuite(tests)
|
||||
_logger.log(logging.INFO, 'running tests %s.', mod_mod.__name__)
|
||||
suite(registry._assertion_report)
|
||||
|
|
@ -1357,6 +1348,7 @@ def load_test_file_py(registry, test_file):
|
|||
finally:
|
||||
threading.current_thread().testing = False
|
||||
|
||||
|
||||
def preload_registries(dbnames):
|
||||
""" Preload a registries, possibly run a test file."""
|
||||
# TODO: move all config checks to args dont check tools.config here
|
||||
|
|
@ -1381,6 +1373,7 @@ def preload_registries(dbnames):
|
|||
|
||||
# run post-install tests
|
||||
if config['test_enable']:
|
||||
from odoo.tests import loader # noqa: PLC0415
|
||||
t0 = time.time()
|
||||
t0_sql = odoo.sql_db.sql_counter
|
||||
module_names = (registry.updated_modules if update_module else
|
||||
|
|
@ -1400,7 +1393,7 @@ def preload_registries(dbnames):
|
|||
odoo.sql_db.sql_counter - t0_sql)
|
||||
|
||||
registry._assertion_report.log_stats()
|
||||
if not registry._assertion_report.wasSuccessful():
|
||||
if registry._assertion_report and not registry._assertion_report.wasSuccessful():
|
||||
rc += 1
|
||||
except Exception:
|
||||
_logger.critical('Failed to initialize database `%s`.', dbname, exc_info=True)
|
||||
|
|
@ -1421,11 +1414,6 @@ def start(preload=None, stop=False):
|
|||
_logger.warning("Unit testing in workers mode could fail; use --workers 0.")
|
||||
|
||||
server = PreforkServer(odoo.http.root)
|
||||
|
||||
# Workaround for Python issue24291, fixed in 3.6 (see Python issue26721)
|
||||
if sys.version_info[:2] == (3,5):
|
||||
# turn on buffering also for wfile, to avoid partial writes (Default buffer = 8k)
|
||||
werkzeug.serving.WSGIRequestHandler.wbufsize = -1
|
||||
else:
|
||||
if platform.system() == "Linux" and sys.maxsize > 2**32 and "MALLOC_ARENA_MAX" not in os.environ:
|
||||
# glibc's malloc() uses arenas [1] in order to efficiently handle memory allocation of multi-threaded
|
||||
|
|
@ -1471,7 +1459,7 @@ def start(preload=None, stop=False):
|
|||
if watcher:
|
||||
watcher.stop()
|
||||
# like the legend of the phoenix, all ends with beginnings
|
||||
if getattr(odoo, 'phoenix', False):
|
||||
if server_phoenix:
|
||||
_reexec()
|
||||
|
||||
return rc if rc else 0
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue