From 50c102a2e54cb622c3efd44977ccdea7d8449142 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolas=20=C3=89vrard?= Date: Thu, 16 Nov 2023 23:37:19 +0100 Subject: [PATCH] Do not start threads before the end of the evaluation of trytond.application When uwsgi forks workers it can happen that python execute the code from one of the launched thread (eg: the cache listener or trytond-status). In that case python will keep executing the thread and never switch to the main thread. Thus preventing to listen for incoming connections. Closes #12758 --- trytond/trytond/cache.py | 6 +++++- trytond/trytond/config.py | 7 ------- trytond/trytond/status.py | 13 +++++++------ 3 files changed, 12 insertions(+), 14 deletions(-) diff --git a/trytond/trytond/cache.py b/trytond/trytond/cache.py index e830cd6918..3c26c08a73 100644 --- a/trytond/trytond/cache.py +++ b/trytond/trytond/cache.py @@ -151,7 +151,7 @@ class MemoryCache(BaseCache): A key value LRU cache with size limit. """ _reset = WeakKeyDictionary() - _clean_last = dt.datetime.now() + _clean_last = None _default_lower = Transaction.monotonic_time() _listener = {} _listener_lock = defaultdict(threading.Lock) @@ -228,6 +228,10 @@ class MemoryCache(BaseCache): @classmethod def sync(cls, transaction): + if cls._clean_last is None: + cls._clean_last = dt.datetime.now() + return + database = transaction.database dbname = database.name if not _clear_timeout and database.has_channel(): diff --git a/trytond/trytond/config.py b/trytond/trytond/config.py index e6e9ab23d9..997630a945 100644 --- a/trytond/trytond/config.py +++ b/trytond/trytond/config.py @@ -6,10 +6,6 @@ import os import urllib.parse from getpass import getuser -import __main__ as main - -from . import status - __all__ = ['config', 'get_hostname', 'get_port', 'split_netloc', 'parse_listen', 'parse_uri'] logger = logging.getLogger(__name__) @@ -169,6 +165,3 @@ class TrytonConfigParser(configparser.ConfigParser): config = TrytonConfigParser() - -if os.path.basename(getattr(main, '__file__', '')) != 'trytond-stat': - status.start(config.get('database', 'path')) diff --git a/trytond/trytond/status.py b/trytond/trytond/status.py index 2d438ab320..690b8b5a9d 100644 --- a/trytond/trytond/status.py +++ b/trytond/trytond/status.py @@ -10,6 +10,8 @@ import time from collections import namedtuple from contextlib import contextmanager +from trytond.config import config + status = dict() logger = logging.getLogger(__name__) address = 'trytond-stat.socket' @@ -17,13 +19,12 @@ address = 'trytond-stat.socket' Process = namedtuple('Process', ['start_time', 'request']) _PID = None -_PATH = None _LOCK = threading.Lock() @contextmanager def processing(request): - start(_PATH) # check if running thread + start() # check if running thread process = Process(time.perf_counter(), request) status[id(process)] = process try: @@ -74,17 +75,17 @@ def dumper(path): time.sleep(60) -def start(path): - global _PID, _PATH +def start(): + global _PID if not hasattr(socket, 'AF_UNIX'): return - if _PID != os.getpid() and path: # Quick test without lock + if _PID != os.getpid(): # Quick test without lock with _LOCK: if _PID != os.getpid(): + path = config.get('database', 'path') threading.Thread( target=dumper, args=(path,), daemon=True).start() _PID = os.getpid() - _PATH = path def listen(path, callback=None):