summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXavierDo <xdo@odoo.com>2019-02-18 16:23:35 +0000
committerXavierDo <xdo@odoo.com>2019-02-28 15:49:04 +0000
commita95756faac9233a4e831695c2a7cd4f22e4bfac2 (patch)
tree1f459cff6728b62fa7b57633aa6617abb49b69a4
parent6edd699ee95264028129d8dace48383252e120e8 (diff)
[FIX] bus: gc event at the end of a polling
When making a poll, an event is registered on each channel. Once a notification is sent on a channel, only the events of the notified channel are removed. A pointer to the event is kept in all other channel the user subscribes to until those channel are notified. Since a user usually has many mail.channels but only a few active ones, a new event and a bunch of pointers are created at each poll and never removed. This fix simply remove the pointers to the current event at the end of a poll. closes odoo/odoo#31215 Signed-off-by: Toufik Benjaa (tbe) <tbe@odoo.com>
-rw-r--r--addons/bus/models/bus.py10
1 files changed, 8 insertions, 2 deletions
diff --git a/addons/bus/models/bus.py b/addons/bus/models/bus.py
index d5d84fa77d2..9350ea805d1 100644
--- a/addons/bus/models/bus.py
+++ b/addons/bus/models/bus.py
@@ -141,7 +141,7 @@ class ImDispatch(object):
event = self.Event()
for channel in channels:
- self.channels.setdefault(hashable(channel), []).append(event)
+ self.channels.setdefault(hashable(channel), set()).add(event)
try:
event.wait(timeout=timeout)
with registry.cursor() as cr:
@@ -150,6 +150,12 @@ class ImDispatch(object):
except Exception:
# timeout
pass
+ finally:
+ # gc pointers to event
+ for channel in channels:
+ channel_events = self.channels.get(hashable(channel))
+ if channel_events and event in channel_events:
+ channel_events.remove(event)
return notifications
def loop(self):
@@ -170,7 +176,7 @@ class ImDispatch(object):
# dispatch to local threads/greenlets
events = set()
for channel in channels:
- events.update(self.channels.pop(hashable(channel), []))
+ events.update(self.channels.pop(hashable(channel), set()))
for event in events:
event.set()