From a373091c64085c53fd469c647c02f6feddcb5dcf Mon Sep 17 00:00:00 2001 From: Fabio Manganiello Date: Sat, 20 Apr 2024 18:31:44 +0200 Subject: [PATCH] Prevent duplicate hook runs. Instead of being a list, the hooks in the hook processor should be backed by by-name and by-value maps. Don't insert a hook if its exact backing method has already been inserted. This is actually very common when hooks are defined as Python snippets imported in other scripts too. --- platypush/event/processor/__init__.py | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/platypush/event/processor/__init__.py b/platypush/event/processor/__init__.py index 24f97074..8df62f61 100644 --- a/platypush/event/processor/__init__.py +++ b/platypush/event/processor/__init__.py @@ -1,4 +1,5 @@ import sys +from typing import Callable, List, Union from ..hook import EventHook @@ -20,10 +21,23 @@ class EventProcessor: if hooks is None: hooks = Config.get_event_hooks() - self.hooks = [] + self._hooks_by_name = {} + self._hooks_by_value_id = {} for name, hook in hooks.items(): - h = EventHook.build(name=name, hook=hook) - self.hooks.append(h) + self.add_hook(name, hook) + + @property + def hooks(self) -> List[EventHook]: + return list(self._hooks_by_name.values()) + + def add_hook(self, name: str, desc: Union[dict, Callable]): + hook_id = id(desc) + if hook_id in self._hooks_by_value_id: + return # Don't add the same hook twice + + hook = EventHook.build(name=name, hook=desc) + self._hooks_by_name[name] = hook + self._hooks_by_value_id[hook_id] = hook @staticmethod def notify_web_clients(event):