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
This commit is contained in:
Nicolas Évrard committed 2023-11-16 23:37:19 +01:00
1 parent 4779c72913
commit 50c102a2e5
3 files changed
+12 -14

No files matched your search

+5 -1
View File
@@ -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():
-7
View File
@@ -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'))
+7 -6
View File
@@ -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):