Priority-based algorithm for hooks, solves #41

This commit is contained in:
Fabio Manganiello 2018-01-04 19:19:56 +01:00
parent 325193e027
commit fa34b05c6c
2 changed files with 19 additions and 7 deletions

View file

@ -114,13 +114,17 @@ class EventHook(object):
""" Event hook class. It consists of one conditionss and """ Event hook class. It consists of one conditionss and
one or multiple actions to be executed """ 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 """ 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.name = name
self.condition = EventCondition.build(condition or {}) self.condition = EventCondition.build(condition or {})
self.actions = actions self.actions = actions
self.priority = priority or 0
@classmethod @classmethod
@ -134,13 +138,15 @@ class EventHook(object):
condition = EventCondition.build(hook['if']) if 'if' in hook else None condition = EventCondition.build(hook['if']) if 'if' in hook else None
actions = [] actions = []
priority = hook['priority'] if 'priority' in hook else None
if 'then' in hook: if 'then' in hook:
if isinstance(hook['then'], list): if isinstance(hook['then'], list):
actions = [EventAction.build(action) for action in hook['then']] actions = [EventAction.build(action) for action in hook['then']]
else: else:
actions = [EventAction.build(hook['then'])] 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): def matches_event(self, event):

View file

@ -27,17 +27,23 @@ class EventProcessor(object):
def process_event(self, event): def process_event(self, event):
""" Processes an event and runs the matched hooks with the highest score """ """ Processes an event and runs the matched hooks with the highest score """
matched_hooks = [] matched_hooks = set(); priority_hooks = set()
max_score = -sys.maxsize max_score = -sys.maxsize; max_prio = 0
for hook in self.hooks: for hook in self.hooks:
match = hook.matches_event(event) match = hook.matches_event(event)
if match.is_match: if match.is_match:
if match.score > max_score: if match.score > max_score:
matched_hooks = [hook] matched_hooks = set((hook,))
elif match.score == max_score: 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: for hook in matched_hooks:
hook.run(event) hook.run(event)