From 0e9cfb3e84bfb997926449b547001c79482ff889 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolas=20=C3=89vrard?= Date: Wed, 18 Dec 2024 17:08:26 +0100 Subject: [PATCH] Do not refresh the pool when the notification comes from the same process --- trytond/trytond/cache.py | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/trytond/trytond/cache.py b/trytond/trytond/cache.py index 6945411a9f..b304391ab5 100644 --- a/trytond/trytond/cache.py +++ b/trytond/trytond/cache.py @@ -7,6 +7,7 @@ import selectors import threading from collections import OrderedDict, defaultdict from copy import deepcopy +from uuid import uuid4 from weakref import WeakKeyDictionary from sql import Conflict, Table @@ -26,6 +27,8 @@ _select_timeout = config.getint('cache', 'select_timeout') _default_size_limit = config.getint('cache', 'default') logger = logging.getLogger(__name__) +REFRESH_POOL_MSG = "refresh pool" + def _cast(column): class SQLite_DateTime(Function): @@ -69,6 +72,7 @@ class _CacheLocal(local): def __init__(self): self.listeners = {} self.listener_lock = threading.Lock() + self.portable_id = str(uuid4()) class BaseCache(object): @@ -374,10 +378,11 @@ class MemoryCache(BaseCache): if not _clean_timeout and database.has_channel(): database = backend.Database(dbname) conn = database.get_connection() + process_id = cls._local.portable_id + payload = f"{REFRESH_POOL_MSG} {process_id}" try: cursor = conn.cursor() - cursor.execute( - 'NOTIFY "%s", %%s' % cls._channel, ('refresh pool',)) + cursor.execute(f'NOTIFY "{cls._channel}", %s', (payload,)) conn.commit() finally: database.put_connection(conn) @@ -410,11 +415,14 @@ class MemoryCache(BaseCache): conn.poll() while conn.notifies: notification = conn.notifies.pop() - if notification.payload == 'refresh pool': - Pool.refresh(dbname, _get_modules(cursor)) - elif notification.payload: - reset = json.loads(notification.payload) - for name in reset: + payload = notification.payload + if payload and payload.startswith(REFRESH_POOL_MSG): + remote_id = payload[len(REFRESH_POOL_MSG) + 1:] + process_id = cls._local.portable_id + if remote_id != process_id: + Pool.refresh(dbname, _get_modules(cursor)) + elif payload: + for name in json.loads(payload): inst = cls._instances[name] inst._clear(dbname) cls._clean_last = dt.datetime.now()