diff libervia/backend/tools/async_trigger.py @ 4071:4b842c1fb686

refactoring: renamed `sat` package to `libervia.backend`
author Goffi <goffi@goffi.org>
date Fri, 02 Jun 2023 11:49:51 +0200
parents sat/tools/async_trigger.py@524856bd7b19
children e11b13418ba6
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libervia/backend/tools/async_trigger.py	Fri Jun 02 11:49:51 2023 +0200
@@ -0,0 +1,74 @@
+#!/usr/bin/env python3
+
+
+# SAT: a jabber client
+# Copyright (C) 2009-2021 Jérôme Poisson (goffi@goffi.org)
+
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU Affero General Public License for more details.
+
+# You should have received a copy of the GNU Affero General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+"""Misc usefull classes"""
+
+from typing import Tuple, Any
+from . import trigger as sync_trigger
+from . import utils
+from twisted.internet import defer
+
+class TriggerManager(sync_trigger.TriggerManager):
+    """This is a TriggerManager with an new async_point method"""
+
+    @defer.inlineCallbacks
+    def async_point(self, point_name, *args, **kwargs):
+        """This put a trigger point with potentially async Deferred
+
+        All the triggers for that point will be run
+        @param point_name: name of the trigger point
+        @param *args: args to transmit to trigger
+        @param *kwargs: kwargs to transmit to trigger
+            if "triggers_no_cancel" is present, it will be popped out
+                when set to True, this argument don't let triggers stop
+                the workflow
+        @return D(bool): True if the action must be continued, False else
+        """
+        if point_name not in self.__triggers:
+            defer.returnValue(True)
+
+        can_cancel = not kwargs.pop('triggers_no_cancel', False)
+
+        for priority, trigger in self.__triggers[point_name]:
+            try:
+                cont = yield utils.as_deferred(trigger, *args, **kwargs)
+                if can_cancel and not cont:
+                    defer.returnValue(False)
+            except sync_trigger.SkipOtherTriggers:
+                break
+        defer.returnValue(True)
+
+    async def async_return_point(
+        self,
+        point_name: str,
+        *args, **kwargs
+    ) -> Tuple[bool, Any]:
+        """Async version of return_point"""
+        if point_name not in self.__triggers:
+            return True, None
+
+        for priority, trigger in self.__triggers[point_name]:
+            try:
+                cont, ret_value = await utils.as_deferred(trigger, *args, **kwargs)
+                if not cont:
+                    return False, ret_value
+            except sync_trigger.SkipOtherTriggers:
+                break
+        return True, None
+