From fa34b05c6c81063e7bb8fc6486a0c51e0969ae56 Mon Sep 17 00:00:00 2001 From: Fabio Manganiello Date: Thu, 4 Jan 2018 19:19:56 +0100 Subject: [PATCH] Priority-based algorithm for hooks, solves #41 --- platypush/event/hook.py | 12 +++++++++--- platypush/event/processor/__init__.py | 14 ++++++++++---- 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/platypush/event/hook.py b/platypush/event/hook.py index fb81e785ee..788acf617e 100644 --- a/platypush/event/hook.py +++ b/platypush/event/hook.py @@ -114,13 +114,17 @@ class EventHook(object): """ Event hook class. It consists of one conditionss and one or multiple actions to be executed """ - def __init__(self, name, condition=None, actions=[]): + def __init__(self, name, priority=None, condition=None, actions=[]): """ Construtor. Takes a name, a EventCondition object and a list of - EventAction objects as input """ + EventAction objects as input. It may also have a priority attached + as a positive number. If multiple hooks match against an event, + only the ones that have either the maximum match score or the + maximum pre-configured priority will be run. """ self.name = name self.condition = EventCondition.build(condition or {}) self.actions = actions + self.priority = priority or 0 @classmethod @@ -134,13 +138,15 @@ class EventHook(object): condition = EventCondition.build(hook['if']) if 'if' in hook else None actions = [] + priority = hook['priority'] if 'priority' in hook else None + if 'then' in hook: if isinstance(hook['then'], list): actions = [EventAction.build(action) for action in hook['then']] else: actions = [EventAction.build(hook['then'])] - return cls(name=name, condition=condition, actions=actions) + return cls(name=name, condition=condition, actions=actions, priority=priority) def matches_event(self, event): diff --git a/platypush/event/processor/__init__.py b/platypush/event/processor/__init__.py index 06ce12e632..6753ab8a75 100644 --- a/platypush/event/processor/__init__.py +++ b/platypush/event/processor/__init__.py @@ -27,17 +27,23 @@ class EventProcessor(object): def process_event(self, event): """ Processes an event and runs the matched hooks with the highest score """ - matched_hooks = [] - max_score = -sys.maxsize + matched_hooks = set(); priority_hooks = set() + max_score = -sys.maxsize; max_prio = 0 for hook in self.hooks: match = hook.matches_event(event) if match.is_match: if match.score > max_score: - matched_hooks = [hook] + matched_hooks = set((hook,)) elif match.score == max_score: - matched_hooks.append(hook) + matched_hooks.add(hook) + if hook.priority > max_prio: + priority_hooks = set((hook,)) + elif hook.priority == max_prio: + priority_hooks.add(hook) + + matched_hooks.update(priority_hooks) for hook in matched_hooks: hook.run(event)