diff options
| author | XavierDo <xdo@odoo.com> | 2019-02-18 16:23:35 +0000 |
|---|---|---|
| committer | XavierDo <xdo@odoo.com> | 2019-02-28 15:49:04 +0000 |
| commit | a95756faac9233a4e831695c2a7cd4f22e4bfac2 (patch) | |
| tree | 1f459cff6728b62fa7b57633aa6617abb49b69a4 | |
| parent | 6edd699ee95264028129d8dace48383252e120e8 (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.py | 10 |
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() |
